MEF和Unity有什么不同?
我刚开始学习DI(我正在WPF / Silverlight上工作,但是我有一个转移到ASP.NET的计划)。 在我从互联网上读到一些DI文章后,我有两个框架,MEF和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旨在允许dynamic发现零件。 例如,使用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(); } }
为了适应这样的dynamic组合场景,MEF有一个“稳定构图”的概念,这意味着当它在某处丢失依赖时,只会将该部分标记为不可用,并将继续构图。
稳定的构图可能非常有用 ,但是它也使debugging失败的构图变得非常困难 。 所以如果你不需要dynamic发现零件和“稳定的组成”,我会使用一个常规的DI容器而不是MEF。 与MEF不同的是,常规DI容器会在缺less依赖关系时为您提供明确的错误消息。
通过使用与MEF集成的DI容器(如Autofac) ,也可能获得两全其美的效果 。 使用Autofac编写核心应用程序,使用MEF编写需要dynamic扩展的部分。
DI有很多select。 首先你应该认识到DI不是关于工具,而是关于模式和原则。 没有工具就可以使用DI。 如果你这样做,我们称之为穷人的DI 。
不过,也就是说, 有很多可用于.NET的DI容器 。 团结只是其中之一。
MEF看起来很像DI容器,但目前解决了另一个问题 – 即可扩展性问题。 它不使用组件的外部configuration(所有DI容器都使用它),而是使用基于属性的发现机制 。