我们通常只在我们的应用程序中引用 Microsoft.Practices.Unity.dll。我们只使用基本功能,这很好用。在一个应用程序中,使用反射的行为导致 Unity 需要另一个 DLL。
例如,创建一个控制台应用程序并仅引用 Microsoft.Practices.Unity(文件版本 2.0.414.0)。输入以下代码并运行它:
class Program
{
static void Main()
{
using (var container = new UnityContainer())
{
container.RegisterType<IDoSomething, ConcreteDoSomething>();
var thing = container.Resolve<IDoSomething>();
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,代码就抛出了异常。但是 Unity 类型无法实现我们的接口!
我不明白如何简单地反映程序集导致核心 Unity 程序集需要另一个依赖项。