MEF 和 Unity 之间以及用途有何不同?

发布于 2024-11-06 07:57:25 字数 124 浏览 1 评论 0原文

我刚刚开始学习 DI(我正在研究 WPF/Silverlight,但我计划转向 ASP.NET)。在我从互联网上阅读了一些 DI 文章后,我对两个框架感兴趣,MEF 和 Unity。我想知道它们在现实世界中有何不同,以及哪一个更适合。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

念﹏祤嫣 2024-11-13 07:57:25

主要区别在于,通过 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 有一个“稳定组合”的概念,这意味着当它在某个地方遇到缺少依赖项时,它只会将该部分标记为不可用,并无论如何都会继续组合。

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

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

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

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:

[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 DirectoryCatalog you can design your application in such a way that you can extend it by simply dropping new DLLs in the application folder.

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 Program constructor:

[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.

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.

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.

转身以后 2024-11-13 07:57:25

进行 DI 有很多选择。首先你应该意识到 DI 不是关于工具,而是关于模式和原则。无需工具即可正常使用 DI。如果您这样做,我们称之为穷人的 DI

不过,有很多可用于 .NET 的 DI 容器。统一只是其中之一。

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

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.

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文