这是一个老问题,但是没有一个答案适用于我。
我在使用autofac与asp.net core webapi项目(.net 6)。
这就是我需要获取程序集的地方:
host
// autofac
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
// autofac container
.ConfigureContainer<ContainerBuilder>(builder => {
// get assemblies for register
var assemblies = ???
builder.RegisterAssemblyTypes(assemblies).AsImplementedInterfaces()...
});
该项目由DDD设计,依赖关系如下:
webapi -> domain,infra
infra -> domain
针对我的情况:
AppDomain.CurrentDomain.GetAssemblies()
只能获取 webapi 程序集。
顺便说一下:Assembly.GetEntryAssembly()
也可以获取 webapi 程序集。
webapiAssembly.GetReferencedAssemblies()
只能获取域项目的程序集。找不到基础架构程序集。
为什么 GetReferencedAssemblies() 没有按预期获取所有引用的程序集?
这是因为在我的项目中,webapi 使用了一个存储库接口,该接口在域中定义,但在基础架构中实现。Webapi 项目没有直接依赖基础架构层(使用基础架构中定义的类/接口)。因此,基础架构程序集未被包含。
如果 webapi 直接依赖于基础架构,则使用 GetReferencedAssemblies() 就可以了。
这里有另一个适合我的解决方案:
使用 Microsoft.Extensions.DependencyModel(nuget 包)中包含的 DependencyContext 获取我想要的所有程序集(webapi、域、基础架构)。
public static class AssemblyHelper
{
public static Assembly[] GetAllAssemblies(string namespaceStartName = "")
{
var ctx = DependencyContext.Default;
var names = ctx.RuntimeLibraries.SelectMany(rl => rl.GetDefaultAssemblyNames(ctx));
if (!string.IsNullOrWhiteSpace(namespaceStartName))
{
if (namespaceStartName.Substring(namespaceStartName.Length - 1, 1) != ".")
namespaceStartName += ".";
names = names.Where(x => x.FullName != null && x.FullName.StartsWith(namespaceStartName)).ToArray();
}
var assemblies = new List<Assembly>();
foreach (var name in names)
{
try
{
assemblies.Add(Assembly.Load(name));
}
catch { }
}
return assemblies.ToArray();
}
}