c# - 反射程序集导致 Unity 需要 Microsoft.Practices.ServiceLocation

标签 c# c#-4.0 reflection unity-container

我们通常只在我们的应用程序中引用 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 {}

在我的机器上,输出是:

Something!

Got here...
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Could not load file or assembly 'Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

Now comment out the line

LoadSchemaLoaders();

再次运行,一切正常。

这是生产代码的简化版本。生产代码实际上是动态加载实现接口(interface)的自定义类型。我们一引入 Unity,代码就抛出了异常。但是 Unity 类型无法实现我们的接口(interface)!

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

最佳答案

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

编译器不要求您的应用程序直接引用该 dll...但通过 System.Type 对象进行反射将尝试加载 Unity 引用的 dll。

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

作为变通方法,您可以将 Assembly.GetTypes() 调用包含在 try/catch block 中。

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

关于c# - 反射程序集导致 Unity 需要 Microsoft.Practices.ServiceLocation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10050027/

相关文章:

.net - c# 环境中动态功能运行时的 future ?

c# - 比较两个函数的负载/性能

c# - 扫描自定义属性的所有类和方法的最佳实践

Java - 反射提取类

c# - System.Reflection - 如何调用子级别类型的 getter 方法?

在任意两个数字基数之间转换的 C# 代码

c# - 在 RichTextBox 中格式化文本时的性能问题

c# - 窗体 : scroll programmatically

c# - 如何在 UWP 应用程序中生成二维码?

c# - ASP.NET MVC NerdDinner 教程问题