.net - MEF 和 Unity 之间以及用途有何不同?

标签 .net dependency-injection unity-container mef

我刚刚开始学习 DI(我正在研究 WPF/Silverlight,但我计划转向 ASP.NET)。在我从互联网上阅读了一些 DI 文章后,我对两个框架感兴趣,MEF 和 Unity。我想知道它们在现实世界中有何不同,以及哪一个比较适合。

最佳答案

主要区别在于,通过 Unity,您将显式注册要在组合中使用的每个类:

var container = new UnityContainer();
container.RegisterType<IFoo,Foo>();
container.RegisterType<IBar,Bar>();
...
var program = container.Resolve<Program>();
program.Run();

另一方面,在 MEF 中,您可以用属性标记类,而不是在其他地方注册它们:

[Export(typeof(IFoo))]
public Foo
{
   ...
}

乍一看,这似乎是一个细微的语法差异,但实际上比这更重要。 MEF 旨在允许动态发现零件。例如,使用DirectoryCatalog,您可以设计应用程序,只需将新的 DLL 放入应用程序文件夹即可对其进行扩展。

在此示例中,MEF 将查找并实例化给定目录中具有 [Export(typeof(IPlugin))] 属性的所有类,并将这些实例传递给 Program 构造函数:

[Export]
public class Program
{
    private readonly IEnumerable<IPlugin> plugins;

    [ImportingConstructor]
    public Program(
       [ImportMany(typeof(IPlugin))] IEnumerable<IPlugin> plugins)
    {
        this.plugins = plugins;
    }

    public void Run()
    {
        // ...
    }
}

入口点:

public static void Main()
{
    using (var catalog = new DirectoryCatalog(".","*"))
    using (var container = new CompositionContainer(catalog))
    {
        var program = container.GetExportedValue<Program>();
        program.Run();
    }
}

为了适应这种动态组合场景,MEF 有一个“稳定组合”的概念,这意味着当它在某个地方遇到缺少依赖项时,它只会将该部分标记为不可用,并无论如何都会继续组合。

Stable composition can be quite useful ,但这也使得 very difficult to debug a failed composition 。因此,如果您不需要动态发现部件和“稳定组合”,我会使用常规 DI 容器而不是 MEF。与 MEF 不同,常规 DI 容器会在缺少依赖项时向您提供清晰的错误消息。

还可以通过使用与 MEF 集成的 DI 容器来获得两全其美的效果,例如 Autofac 。使用Autofac来编写核心应用程序,并使用MEF来编写需要动态扩展的部分。

关于.net - MEF 和 Unity 之间以及用途有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5949566/

相关文章:

c# - 在非常大的集合 (10,000) 中更改值

c# - 如何通过 Linq 过滤一对多关系的查询

android - 在没有第三方框架的情况下测试 Android Activity 时如何注入(inject)依赖项?

c# - 不引用实现的 ASP.NET Core 依赖注入(inject)

c# - 计算一条线的精确像素

c# - 使用 C# 连接/重试连接的最有效方法?

java - @DependsOn 注解的逆

c# - Unity ICallHandler 与 IInterceptionBehavior

c# - 多层应用程序中的依赖注入(inject)

unity-container - 如何替换我的 Unity 解决方案中过时的 Microsoft.Practices.Unity.Configuration.ContainerElement.Configure 方法?