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

Ano*_*ous 53 .net dependency-injection mef unity-container

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

Wim*_*nen 64

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

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

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

[Export(typeof(IFoo))]
public Foo
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

乍一看,这看起来像一个小的语法差异,但它实际上比这更重要.MEF旨在允许动态发现零件.例如,使用a 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()
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

入口点:

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

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

稳定的组合可能非常有用,但它也使得调试失败的组合物变得非常困难.因此,如果您不需要动态发现零件和"稳定的组合",我会使用常规DI容器而不是MEF.与MEF不同,当缺少依赖项时,常规DI容器将为您提供明确的错误消息.

通过使用与MEF集成的DI容器(如Autofac),也可能获得两全其美的效果.使用Autofac组成核心应用程序,并使用MEF来处理需要动态扩展的部分.

  • @Freddy:目前尚不清楚你在评论我的答案的哪一部分.我确实写道"调试失败的作品非常困难"并且链接到我的博客文章.我在哪里说这很容易? (2认同)

Mar*_*ann 20

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

但是,也就是说,有很多可用于.NET的DI容器.Unity只是其中之一.

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

  • 读这个人的书!! 它让我走上了正义之路:D.http://www.manning.com/seemann/ (9认同)