【问题标题】:Can Unity Container Load Assemblies Dynamically?Unity 容器可以动态加载程序集吗?
【发布时间】:2011-10-20 17:48:44
【问题描述】:

我正在开发一个应用程序。我希望统一解决我的类型,而不必引用主项目中的程序集。我通过使用配置类型注册来自动加载程序集,但除非我添加对包含依赖项的程序集的引用,否则它似乎不起作用。

是否可以从当前目录的程序集中加载类型?

谢谢!

【问题讨论】:

  • 你使用的是xml配置吗?

标签: c# unity-container


【解决方案1】:

听起来你想要 MEF 而不是 Unity。 MEF 专为动态发现而设计。

阅读此问题的答案:What is different between and purpose of MEF and Unity?

【讨论】:

    【解决方案2】:

    我知道这是不久前提出的问题,但对于任何寻找答案的人,您必须确保 Unity 可以在运行时找到程序集。因此,您要么需要将它们放在 GAC 中,要么将程序集 dll 放在与可执行文件相同的目录中。如果您为依赖项使用不同的目录并且有一个 Web 应用程序,那么您必须在 web.config 中设置探测元素:

    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <probing privatePath="Dependencies" />
        </assemblyBinding>
    </runtime>
    

    对于那些正在寻找有关如何解决此问题的代码的人,以下代码将在您定义的目录中查找所有程序集并将它们注册到 Unity:

    string DependenciesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Dependencies");
    string[] Dependencies   = Directory.GetFiles(DependenciesPath, DLL_PATTERN);
    
    Dictionary<Type, Type> pluginMappings = new Dictionary<Type, Type>();
    
    //Load Dependency Assemblies
    foreach (string fileName in Dependencies)
    {
        string assemblyName = Path.GetFileNameWithoutExtension(fileName);
        if (assemblyName != null)
        {
            Assembly pluginAssembly = Assembly.Load(assemblyName);
    
            foreach (Type pluginType in pluginAssembly.GetTypes())
            {
                if (pluginType.IsPublic) //Only look at public types
                {
                    if (!pluginType.IsAbstract)  //Only look at non-abstract types
                    {
                        //Gets a type object of the interface we need the plugins to match
                        Type[] typeInterfaces = pluginType.GetInterfaces();
                        foreach (Type typeInterface in typeInterfaces)
                        {
                            if (pluginMappings.ContainsKey(typeInterface))
                            {
                                throw new DuplicateTypeMappingException(typeInterface.Name, typeInterface, pluginMappings[typeInterface], pluginType);
                            }
                            pluginMappings.Add(typeInterface, pluginType);
                        }
                    }
                }
            }
        }
    }
    
    //Web API resolve dependencies with Unity
    IUnityContainer container = new UnityContainer();
    foreach (var mapping in pluginMappings)
    {
        container.RegisterType(mapping.Key, mapping.Value);
    }
    

    【讨论】:

      【解决方案3】:

      提供帮助可能有点晚,但是如果您使用 XML 配置方法,Unity 可以动态加载程序集,注册每个程序集,然后相应地注册类型。一段时间以来,我一直在使用这个过程对一个非常依赖 DI 的框架进行小的扩展。

      如果您遇到 Unity 无法解析在主应用程序中注册但在另一个未引用程序集中定义的类型的问题,并且引用该程序集可以解决该问题,则很可能意味着它只是没有被复制到应用程序的输出目录。默认情况下,只会自动复制直接引用的程序集。如果它们是手动复制或通过构建后事件复制的,或者如果您重定向构建路径以便将未引用的程序集构建到应用程序的输出目录,它应该工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-07
        • 1970-01-01
        • 2011-10-12
        • 2020-04-14
        • 1970-01-01
        • 2016-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多