停止RegisterAssemblyModules重新扫描已经扫描过的程序集?

时间:2014-06-25 09:43:24

标签: .net dependency-injection autofac

我的情况:

我需要告诉Autofac构建器加载引用的程序集。到目前为止它还没有自己加载,在引导加载程序完成配置容器之前我需要它。

public class AppRegisterModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);
    }
}

这一切都有效,PluginManagerRegistrationModule加载完全正常。

我现在担心的是,我无法知道我是否已经要求建筑商加载该组件。即我的框架是许多程序集,它们有自己的注册模块,它们依赖于它们。我还可以看到交叉依赖会创建一个循环循环(虽然我没有交叉依赖)。

目前,我可以看到:

 builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);
 builder.RegisterAssemblyModules(typeof (IPluginManager).Assembly);

...确实运行注册模块两次,我确实得到了重复的注册和重复的已解析类型(IEnumerable<>)。

有什么办法可以避免重复吗?

1 个答案:

答案 0 :(得分:0)

我的解决方案是在到达

之前预先加载所有模块和程序集
containerBuilder
   .RegisterAssemblyModules(
       AppDomain.CurrentDomain.GetAssemblies());

private void PreConfigureRegistrationModules()
{
    var parsedAssemblies = new List<Assembly>()
    {
        typeof (Autofac.Core.IModule).Assembly
    };

    do
    {
        var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();

        var unparsed = loadedAssemblies
            .Where(x => parsedAssemblies.Contains(x) == false)
            .SelectMany(x => x.GetTypes())
            .Where(x => typeof (Autofac.Core.IModule).IsAssignableFrom(x))
            .Where(x => x.IsInterface == false)
            .Where(x => x.IsAbstract == false)
            .ToList();

        var unparsedAssemblies = unparsed
            .Select(x => x.Assembly)
            .Distinct()
            .ToList();

        if (unparsed.Count == 0)
            return;

        unparsed.ForEach(x => Activator.CreateInstance(x));

        parsedAssemblies.AddRange(unparsedAssemblies);

    } while (true);
}

然后在任何需要在RegisterAssemblyModules之前预加载引用程序集的注册模块中,我添加一些东西来强制程序集加载

public class AppRegisterModule : Autofac.Module
{
    static AppRegisterModule()
    {
        if (typeof (IPluginManager).Assembly == null)
            throw new InvalidOperationException();
    }
}

如果你扫描一个程序集两次,它不能直接回答发生的重复,但它是我的解决方法。