c# – Autofac:如何加载引用但未直接使用的程序集

我们使用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));
}

我已将程序集设置为“复制本地”,但无效.我读到了一个Copy Local错误,并尝试了一些不起作用的解决方法.

有没有人能够解决这个问题?看起来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

解决方法:

这应该对你有帮助.它接受bin文件夹中的所有程序集,从名称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();

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

上一篇:c# – Autofac注册并使用名称解析


下一篇:c# – 如何使用Xamarin和Autofac将构造函数依赖项注入ViewModel?