.net MEF 和 Unity 的区别和目的是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5949566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 15:33:47  来源:igfitidea点击:

What is different between and purpose of MEF and Unity?

.netdependency-injectionunity-containermef

提问by Anonymous

I just start study DI (I'm working on WPF/Silverlight but I have a plan to move to ASP.NET). After I read some DI articles from internet there are two Frameworks that I'm interested in, MEF and Unity. I want to know what is the real-world different between them and which one is good to go.

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

回答by Wim Coenen

The main difference is that with unity you will explicitly register each class you want to use in the composition:

主要区别在于,使用 unity,您将显式注册要在组合中使用的每个类:

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

In MEF on the other hand, you mark classes with attributes instead of registering them somewhere else:

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

[Export(typeof(IFoo))]
public Foo
{
   ...
}

At first sight this looks like a minor syntactic difference, but it is actually more important than that. MEF is designed to allow for the dynamic discovery of parts. For example, with a DirectoryCatalogyou can design your application in such a way that you can extend it by simply dropping new DLLs in the application folder.

乍一看,这看起来是一个很小的语法差异,但实际上比这更重要。MEF 旨在允许动态发现零件。例如,DirectoryCatalog您可以通过将新的 DLL 放到应用程序文件夹中来扩展它的方式来设计您的应用程序。

In this example, MEF will find and instantiate all classes with an [Export(typeof(IPlugin))]attribute in the given directory and passes those instances to the Programconstructor:

在此示例中,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()
    {
        // ...
    }
}

Entry point:

入口点:

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

To accommodate such dynamic composition scenarios, MEF has a concept of "stable composition", which means that when it runs into a missing dependency somewhere it will simply mark the part as unavailable and will continue the composition anyway.

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

Stable composition can be quite useful, but it also makes it very difficult to debug a failed composition. So if you don't need dynamic discovery of parts and "stable composition", I would use a regular DI container instead of MEF. Unlike MEF, regular DI containers will give you clear error messages when a dependency is missing.

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

It might also be possible to get the best of both worlds by using a DI container which integrates with MEF, like Autofac. Use Autofac to compose the core application, and MEF for the parts which need to be dynamically extensible.

通过使用与 MEF 集成的 DI 容器(例如Autofac ),也可以两全其美。核心应用程序使用Autofac,需要动态扩展的部分使用MEF。

回答by Mark Seemann

There are lots of options for doing DI. First of all you should realize that DI isn't about tools, but rather about patterns and principles. You can use DI just fine without a tool. If you do that, we call it Poor Man's DI.

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

However, that said, there are lots of DI Containers available for .NET. Unity is just one of them.

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

MEF looks a lot like a DI Container, but currently solves a different problem - that of extensibility. Instead of external configuration of components (which all DI Containers use) it uses an attribute-based discovery mechanism.

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