【发布时间】:2016-02-22 00:23:04
【问题描述】:
我们使用 Autofac for DI 创建了一个 WebApi 解决方案。我们将 autofac 的引导分解为一个单独的项目。这样,我们的 WebApi 项目只引用了我们的 Bootstrap 和 Contracts 项目。然后,我们的引导项目引用所有其他程序集并将所有内容连接在一起。我喜欢这种关注点分离的设计。
我们可以按如下方式手动加载我们的程序集 - 我们的“AutofacModule”类包含注册每个模块(程序集)所需的信息。
ContainerBuilder builder = new Autofac.ContainerBuilder();
builder.RegisterModule(new Business.AutofacModule());
builder.RegisterModule(new Data.AutofacModule());
builder.RegisterModule(new Services.AutofacModule());
etc...
这可行,但需要对每个程序集进行硬编码。我们正在尝试使这种动态化,以便我们可以循环遍历所有引用的程序集,如下所示。
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
foreach (var assembly in assemblies)
{
builder.RegisterAssemblyModules(assembly);
}
这应该有效,但无效。问题是.Net 确定引导项目中实际上并未使用各种程序集并且不加载它们(试图优化?)。所以我们的一些程序集永远不会加载。
我还尝试了以下方法来遍历 bin 目录以查找所有程序集。但是,在编译期间,.Net 不会将未引用的程序集移动到 bin 目录中,因此它们也不存在。
string assemblyPath = System.IO.Path.Combine(
System.AppDomain.CurrentDomain.BaseDirectory, "bin");
var allAssemblies = new List<Assembly>();
foreach (string dll in Directory.GetFiles(assemblyPath, "*.dll"))
{
allAssemblies.Add(Assembly.LoadFile(dll));
}
我已将程序集设置为“复制本地”,但这不起作用。我阅读了有关复制本地错误的信息,并尝试了解决方法,但这些错误也不起作用。
有人能解决这个问题吗?看起来 Autofac 会提供一个解决方案,但我发现的只是他们文档上的一个待办事项页面: http://autofac.readthedocs.org/en/latest/faq/isolate-autofac.html
以下两个问题相似,但没有一个建议的解决方案能够克服所需程序集不在 bin 目录中的事实。
Not all assemblies are being loaded into AppDomain from the bin folder
Loading all referenced assemblies .NET even if not used explicitly in code
最后,我很好奇,这是 Autofac 特有的问题吗?其他 DI 容器是如何解决这个问题的?我为 NInject 发现了一个类似的问题。 Loading unreferenced dll MVC Ninject
【问题讨论】:
-
我正在使用 Autofac 在运行时使用“.RegisterAssemblyModules”方法从程序集中动态加载模块,它就像一个魅力。唯一的要求是任何应该加载的程序集都必须以特定的后缀(对于 Directory.GetFiles)结尾,例如“*.Plugin.dll”。
-
谢谢@Diets。我们的问题是引导项目引用但不直接使用我们的许多程序集。所以我认为编译器认为它们没有必要,所以它永远不会将它们移动到 bin 目录中。所以我没有什么要加载的。
-
我的所有“*.Plugin.dll”文件都通过一个为发布收集程序集的构建后操作移动到 \bin 文件夹。
标签: c# .net asp.net-web-api dependency-injection autofac