我刚开始学习 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旨在允许动态发现部件。例如,使用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();
}
}
有很多选项可用于进行DI。首先,您应该意识到DI不是关于工具,而是关于模式和原则。您可以在没有工具的情况下很好地使用DI。如果您这样做,我们称它为“Poor Man's DI”。
但是,话虽如此,.NET有许多可用于DI的容器。Unity只是其中之一。
MEF看起来很像DI容器,但目前解决的是不同的问题——即可扩展性问题。它使用基于属性的发现机制,而不是组件的外部配置(所有DI容器都使用这种方式)。