我刚刚开始学习 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/