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