Чем отличается MEF и Unity от цели? - PullRequest
51 голосов
/ 10 мая 2011

Я только начинаю изучать DI (я работаю над WPF / Silverlight, но у меня есть план по переходу на ASP.NET). После того, как я прочитал некоторые статьи DI из Интернета, меня интересуют две фреймворки: MEF и Unity. Я хочу знать, чем отличается реальный мир от них, и какой из них хорош.

Ответы [ 2 ]

63 голосов
/ 10 мая 2011

Основное отличие состоит в том, что с единицей вы будете явно регистрировать каждый класс, который хотите использовать в композиции:

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-контейнеры будут давать вам четкие сообщения об ошибках, когда отсутствует зависимость.

Возможно также получить лучшее из обоих миров, используя DI-контейнер, который интегрируется с MEF, например Autofac .Используйте Autofac для создания основного приложения и MEF для частей, которые должны быть динамически расширяемыми.

19 голосов
/ 10 мая 2011

Есть много вариантов для DI. Прежде всего вы должны понимать, что DI не об инструментах, а о шаблонах и принципах. Вы можете использовать DI просто отлично без инструмента. Если вы сделаете это, мы назовем это Бедняжка DI .

Однако, как говорится, есть много DI-контейнеров, доступных для .NET . Единство - только один из них.

MEF очень похож на DI-контейнер, но в настоящее время решает другую проблему - проблему расширяемости. Вместо внешней конфигурации компонентов (которую используют все контейнеры DI) используется механизм обнаружения на основе атрибутов .

...