Autofac: How to load assemblies that are referenced but not directly used

让人想犯罪 __ 提交于 2019-12-03 08:51:01

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.

var assemblies = Directory.EnumerateFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll", SearchOption.TopDirectoryOnly)
   .Where(filePath => Path.GetFileName(filePath).StartsWith("your name space"))
   .Select(Assembly.LoadFrom);

var builder = new ContainerBuilder();

builder.RegisterAssemblyTypes(assemblies.ToArray())
   .Where(t => typeof(ITransientDependency).IsAssignableFrom(t))
   .AsImplementedInterfaces();

//Short answer

Have you seen this: http://docs.autofac.org/en/latest/faq/iis-restart.html It looks like you can scan the referenced assemblies and force them to load.

//Suggestion (or opinion if you like)

Personally I wouldn't have assemblies loaded that weren't going to be used just to be able to have a separate project for the bootstrapping. I don't see the benefit of having it in it's own project. Keep in mind that DI is just that, you are injecting your dependencies of "that" project. Each project can have it's own dependencies and the separation of concern comes from the bootstrapping class, not that it's in it's own project. If you needed to break out just your business logic project into a nuget package that other projects in your company would use you would not want them to also have to download the DI project package that in turn now needs other packages that it may never use. If your dependencies are contained in the project that needed them it becomes modular and extensible. This part of the answer is debatable of course but should be considered at the least.

In case you have multiple projects in your solution, each with their own IoC container class, use the following to load all assemblies, and then register each module in that Assembly.

This is an extension method of the ContainerBuilder.

public static class ContainerBuilderExtensions
{
    public static void ScanAssembly(this ContainerBuilder builder, string searchPattern = "SolutionName.*.dll")
    {
        var path = AppDomain.CurrentDomain.BaseDirectory;
        foreach (var assembly in Directory.GetFiles(path, searchPattern).Select(Assembly.LoadFrom))
        {
            builder.RegisterAssemblyModules(assembly);
        }
    }
}

The above can be called on an instance of your ContainerBuilder as follow:

builder.ScanAssembly()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!