.NET?Core?Web?APi类库内嵌运行的方法(.net core 类库之间的依赖)没想到

随心笔谈3年前发布 admin
260 0 0

文章摘要

该代码实现了一个功能,用于动态加载和填充`ApplicationPart`中的特征实例。主要逻辑包括: 1. **`PopulateFeature`方法**:遍历配置好的`IApplicationFeatureProvider<TFeature>`实例,调用每个Provider的`PopulateFeature`方法,将特征实例填充到`ApplicationParts`中。 2. **`PopulateDefaultParts`方法**:通过获取指定`entryAssemblyName`的相关`ApplicationPart` assemblies,并通过`ApplicationPartAttribute`获取所有依赖于MVC的依赖项,确保所有必要的`ApplicationPart`实例被加载和处理。 3. **`GetApplicationPartAssemblies`方法**:通过`Assembly.Load`和`ApplicationPartAttribute`加载相关assemblies,并使用`HashSet`避免重复。 4. **`GetAssemblyClosure`方法**:递归加载当前`assembly`及其所有相关联的assemblies。 总结:该代码实现了一个高效的`ApplicationPart`加载和管理机制,确保所有必要的依赖项被正确加载和处理。

/// <summary>
/// Populates the given <paramref name=”feature”/> using the list of
/// <see cref=”IApplicationFeatureProvider{TFeature}”/>s configured on the
/// <see cref=”ApplicationPartManager”/>.
/// </summary>
/// <typeparam name=”TFeature”>The type of the feature.</typeparam>
/// <param name=”feature”>The feature instance to populate.</param>
public void PopulateFeature<TFeature>(TFeature feature)
{
if (feature==null)
{
throw new ArgumentNullException(nameof(feature));
}

foreach (var provider in FeatureProviders.OfType<IApplicationFeatureProvider<TFeature>>())
{
provider.PopulateFeature(ApplicationParts, feature);
}
}

internal void PopulateDefaultParts(string entryAssemblyName)
{
var assemblies=GetApplicationPartAssemblies(entryAssemblyName);

var seenAssemblies=new HashSet<Assembly>();

foreach (var assembly in assemblies)
{
if (!seenAssemblies.Add(assembly))
{
// “assemblies” may contain duplicate values, but we want unique ApplicationPart instances.
// Note that we prefer using a HashSet over Distinct since the latter isn’t
// guaranteed to preserve the original ordering.
continue;
}

var partFactory=ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var applicationPart in partFactory.GetApplicationParts(assembly))
{
ApplicationParts.Add(applicationPart);
}
}
}

private static IEnumerable<Assembly> GetApplicationPartAssemblies(string entryAssemblyName)
{
var entryAssembly=Assembly.Load(new AssemblyName(entryAssemblyName));

// Use ApplicationPartAttribute to get the closure of direct or transitive dependencies
// that reference MVC.
var assembliesFromAttributes=entryAssembly.GetCustomAttributes<ApplicationPartAttribute>()
.Select(name=> Assembly.Load(name.AssemblyName))
.OrderBy(assembly=> assembly.FullName, StringComparer.Ordinal)
.SelectMany(GetAssemblyClosure);

// The SDK will not include the entry assembly as an application part. We’ll explicitly list it
// and have it appear before all other assemblies \ ApplicationParts.
return GetAssemblyClosure(entryAssembly)
.Concat(assembliesFromAttributes);
}

private static IEnumerable<Assembly> GetAssemblyClosure(Assembly assembly)
{
yield return assembly;

var relatedAssemblies=RelatedAssemblyAttribute.GetRelatedAssemblies(assembly, throwOnError: false)
.OrderBy(assembly=> assembly.FullName, StringComparer.Ordinal);

foreach (var relatedAssembly in relatedAssemblies)
{
yield return relatedAssembly;
}
}

© 版权声明

相关文章