Unity容器可以动态加载程序集吗?

时间:2011-10-20 17:48:44

标签: c# unity-container

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

是否有wat来从当前目录中的程序集加载类型?

谢谢!

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

我知道这是前一段时间被问到的,但是对于任何寻找答案的人来说,你必须确保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);
}

答案 2 :(得分:0)

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

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