Autofac:如何加载引用但未直接使用的程序集 [英] Autofac: How to load assemblies that are referenced but not directly used

查看:422
本文介绍了Autofac:如何加载引用但未直接使用的程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经使用Autofac for DI创建了WebApi解决方案。我们将autofac的引导分解为一个单独的项目。这样,我们的WebApi项目仅引用了Bootstrap和Contracts项目。然后,我们的引导项目引用所有其他程序集,并将所有内容连接在一起。我喜欢这种用于分离关注点的设计。

We have created a WebApi solution using Autofac for DI. We broke out the bootstrapping of our autofac into a separate project. This way, our WebApi project only references our Bootstrap and Contracts projects. Our bootstrap project then references all other assemblies and wires everything together. I like this design for separation of concerns.

我们可以按以下方式手动加载程序集-我们的 AutofacModule类包含注册每个模块(程序集)所需的信息。

We can manually load our assemblies as follows - where our "AutofacModule" classes contain the necessary info to register each module (assembly).

ContainerBuilder builder = new Autofac.ContainerBuilder();
builder.RegisterModule(new Business.AutofacModule());
builder.RegisterModule(new Data.AutofacModule());
builder.RegisterModule(new Services.AutofacModule());
etc...

这可行,但需要对每个程序集进行硬编码。我们正在尝试使它动态化,以便我们可以如下循环所有引用的程序集。

This works, but requires hardcoding each assembly. We are trying to make this dynamic so that we can just loop over all referenced assemblies as follows.

var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
foreach (var assembly in assemblies)
{
    builder.RegisterAssemblyModules(assembly);
}

这应该有效,但无效。问题在于,.Net会确定Bootstrap项目中并未实际使用各种程序集,也不会加载它们(以进行优化?)。因此我们的某些程序集从未加载。

This should work but doesn't. The problem is that .Net determines various assemblies aren't actually used from within the bootstrap project and doesn't load them (in an attempt to optimize?). So some of our assemblies are never loaded.

我还尝试了以下方法循环遍历bin目录以查找所有程序集。但是,在编译过程中,.Net不会将未引用的程序集移动到bin目录中,因此它们也不存在。

I have also tried the following to loop through the bin directory to find all assemblies. However, during compilation, .Net doesn't move the non-referenced assemblies into the bin directory, so they aren't there either.

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));
}

我已将程序集设置为复制本地,该程序无效。我读到一个复制本地错误,并尝试了解决该错误的方法。

I have set the assemblies to Copy Local which didn't work. I read about a Copy Local bug and tried workarounds for that which didn't work either.

有人能解决此问题吗?看来Autofac会提供解决方案,但是我发现他们的文档上只有一个待办事项页面:
http://autofac.readthedocs.org/en/latest/faq/isolate-autofac.html

Has anyone been able to solve this issue? It seems like Autofac would provide a solution, but all I found was a To Do page on their documents: http://autofac.readthedocs.org/en/latest/faq/isolate-autofac.html

以下两个问题相似,但是所提出的解决方案都无法克服以下事实:所需的程序集不在bin目录中。

The following two questions are similar, but none of the proposed solutions overcome the fact that the needed assemblies are not in the bin directory.

并非所有程序集都已从bin文件夹加载到AppDomain中

即使未在代码中明确使用,也要加载所有引用的程序集.NET

最后,我很好奇,这是Autofac特有的问题吗?其他DI容器如何解决此问题?我为NInject找到了类似的问题。
加载未引用的DLL MVC Ninject

Finally, I'm curious, is this an Autofac specific problem? How do other DI containers solve this problem? I found a similar problem for NInject. Loading unreferenced dll MVC Ninject

推荐答案

这应该对您有所帮助。

This should help you. It takes all the assemblies in the bin folder, starting with name MyModule.

   //builder.RegisterType(typeof(IFoo)).AsImplementedInterfaces();
        ContainerBuilder builder = new ContainerBuilder();

        string[] assemblyScanerPattern = new[] { @"MyModule.*.dll"};

        // Make sure process paths are sane...
        Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

        //  begin setup of autofac >>

        // 1. Scan for assemblies containing autofac modules in the bin folder
        List<Assembly> assemblies = new List<Assembly>();
        assemblies.AddRange(
            Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.dll", SearchOption.AllDirectories)
                     .Where(filename => assemblyScanerPattern.Any(pattern => Regex.IsMatch(filename, pattern)))
                     .Select(Assembly.LoadFrom)
            );


        foreach (var assembly in assemblies)
        {
            builder.RegisterAssemblyTypes(assembly )
                .AsImplementedInterfaces();
        }
        var container = builder.Build();

这将加载那些甚至没有被引用的程序集。

This will load those assemblies also which are not even referenced.

这篇关于Autofac:如何加载引用但未直接使用的程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆