反映程序集会导致Unity需要Microsoft.Practices.ServiceLocation

我们通常只在我们的应用程序中引用Microsoft.Practices.Unity.dll。 我们只使用基本function,这很好用。 在一个应用程序中,使用reflection的行为导致Unity需要另一个DLL。

例如,创建一个控制台应用程序并仅引用Microsoft.Practices.Unity(文件版本2.0.414.0)。 输入以下代码并运行它:

class Program { static void Main() { using (var container = new UnityContainer()) { container.RegisterType(); var thing = container.Resolve(); thing.DoSomething(); Console.WriteLine(); LoadSchemaLoaders(); } } public static void LoadSchemaLoaders() { var type = typeof(ISchemaLoader); try { // Get all loaded assemblies, including Unity. // Get all of the types. // Filter for types that ISchemaLoader (custom type) can be assigned from. var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(c => type.IsAssignableFrom(c) && c.IsClass && !c.IsAbstract && !c.IsGenericParameter); Console.WriteLine("Got here..."); types.FirstOrDefault(); } catch (ReflectionTypeLoadException ex) { Console.WriteLine(ex.Message); foreach (Exception exSub in ex.LoaderExceptions) { Console.WriteLine(exSub.Message); } } } } public interface IDoSomething { void DoSomething(); } public class ConcreteDoSomething : IDoSomething { public void DoSomething() { Console.WriteLine("Something!"); } } public interface ISchemaLoader {} 

在我的机器上,输出是:

 什么!

去那里...
无法加载一个或多个请求的类型。 检索LoaderExceptions属性以获取更多信息。
无法加载文件或程序集“Microsoft.Practices.ServiceLocation,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35”或其依赖项之一。 该系统找不到指定的文件。 

现在注释掉这条线

 LoadSchemaLoaders(); 

再次运行它,它的工作原理。

这是生产代码的简化版本。 生产代码实际上是动态加载实现接口的自定义类型。 一旦我们介绍了Unity,代码就抛出了exception。 但Unity类型无法实现我们的界面!

我不明白如何简单地反映组件导致核心Unity程序集需要另一个依赖项。

Unity程序集中的类型,来自Microsoft.Practices.ServiceLocation(可能是IServiceLocator)中定义的接口。

编译器不要求您的应用程序直接引用该DLL …但是反映在System.Type对象上将尝试加载Unity引用的dll。

只有当您反映程序集时才会发生这种情况的原因是Unity在正常情况下可能不会加载引用Microsoft.Practices.ServiceLocation的类型。

作为解决方法,您可以在try / catch块中包含Assembly.GetTypes()调用。

或者,如果将Microsoft.Practices.ServiceLocation dll放在应用程序可以找到它的位置,那么也应该解决该问题。