MEF和Unity有什么不同和目的?

时间:2011-05-10 11:51:26

标签: .net dependency-injection unity-container mef

我刚刚开始学习DI(我正在研究WPF / Silverlight,但我有计划转向ASP.NET)。在我从互联网上阅读了一些DI文章之后,有两个我感兴趣的框架,MEF和Unity。我想知道它们之间的真实世界有什么不同,哪一个是好的。

2 个答案:

答案 0 :(得分:63)

主要区别在于,您将明确注册要在合成中使用的每个类:

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来处理需要动态扩展的部分。

答案 1 :(得分:19)

进行DI有很多选择。首先,您应该意识到DI不是关于工具,而是关于模式和原则。你可以在没有工具的情况下使用DI。如果你这样做,我们称之为穷人的DI

但是,那说there are lots of DI Containers available for .NET。 Unity只是其中之一。

MEF看起来很像DI容器,但目前解决了一个不同的问题 - 可扩展性问题。它不使用组件的外部配置(所有DI容器都使用),而是使用基于属性的发现机制