Кто-нибудь много работал с Microsoft Managed Extensibility Framework (MEF)? Kinda звучит так, будто он пытается быть всем для всех людей - это менеджер надстройки! Это утка, набирая! Мне интересно, есть ли у кого-нибудь опыт, положительный или отрицательный.
В настоящее время мы планируем использовать общую реализацию IoC ala MvcContrib для нашего следующего крупного проекта. Должны ли мы выбросить MEF в микс?
Ответ 1
Мы не стремимся к тому, чтобы MEF был универсальным IoC. Лучший способ подумать о аспектах IoC MEF - это детализация реализации. Мы используем IoC в качестве шаблона, потому что это отличный способ решить проблемы, которые мы планируем решить.
MEF ориентирован на расширяемость. Когда вы думаете о MEF, посмотрите на это как на инвестиции в продвижение нашей платформы. Наши будущие продукты и платформа будут использовать MEF в качестве стандартного механизма для расширения расширяемости. Сторонние продукты и структуры также смогут использовать этот же механизм. Средний "пользователь" MEF будет составлять компоненты, которые MEF будет потреблять и не будет напрямую потреблять MEF в своих приложениях.
Представьте, когда вы хотите расширить нашу платформу в будущем, вы удалите dll в папку bin, и все готово. Приложение с поддержкой MEF загорается с новым расширением. Это видение MEF.
Ответ 2
Это сообщение относится к предварительному просмотру Framework 2.
Итак, я прошел через MEF и написал быстрый "Hello World", который представлен ниже. Я должен сказать, что было легко погрузиться и понять. Система каталогов великолепна и делает расширение MEF очень простым. Это тривиально, чтобы указать его в каталог сборок addin и позволить ему обрабатывать остальные. Наследие MEF ala Prism, безусловно, демонстрируется, но я думаю, что это было бы странно, если бы это не так, учитывая, что обе структуры связаны с композицией.
Я думаю, что вещь, которая больше всего наклеивается на мой craw, - это "волшебство" _container.Compose(). Если вы посмотрите на класс HelloMEF, вы увидите, что поле приветствия никогда не инициализируется никаким кодом, что просто смешно. Я думаю, что предпочитаю, как работают контейнеры IoC, где явным образом прошу контейнер создать объект для вас. Интересно, может ли быть какой-то "ничто" или "пустой" общий инициализатор. то есть.
private IGreetings greetings = CompositionServices.Empty<IGreetings>();
Это по крайней мере заполняет объект "чем-то" до тех пор, пока код компоновки контейнера не запустится, чтобы заполнить его реальным "чем-то". Я не знаю - это немного смахивает на ключевые слова Visual Basic Empty или Nothing, которые мне всегда не нравились. Если у кого-нибудь есть какие-то мысли по этому поводу, я бы хотел их услышать. Может быть, это то, что мне просто нужно преодолеть. Он отмечен большим жирным атрибутом [Import], поэтому ему не нравится полная тайна или что-то еще.
Управление временем жизни объекта не является очевидным, но все по умолчанию является одиночным, если вы не добавили атрибут [CompositionOptions] к экспортированному классу. Это позволит вам указать либо Factory, либо Singleton. Было бы неплохо увидеть, что Pooled добавлен в этот список в какой-то момент.
Я не совсем понимаю, как работают функции утиной печати. Это скорее похоже на внедрение метаданных при создании объекта, а не на утиную печать. И похоже, что вы можете добавить только одну дополнительную утку. Но, как я уже сказал, я не совсем понимаю, как эта функция работает. Надеюсь, я смогу вернуться и заполнить это позже.
Я думаю, было бы неплохо затенять копию DLL, загружаемых каталогом DirectoryPartCatalog. Прямо сейчас библиотеки DLL блокируются, как только MEF их удерживает. Это также позволит вам добавить наблюдателя в каталог и уловить обновленные дополнения. Это было бы очень мило...
Наконец, я беспокоюсь о том, насколько надежны DLL файлы addin и как, или если MEF будет вести себя в частичной среде доверия. Я подозреваю, что приложения, использующие MEF, потребуют полного доверия. Также может быть разумным загрузить дополнительные элементы в свой собственный AppDomain. Я знаю, что это немного портит System.AddIn, но это позволит очень четкое разделение между пользовательскими добавлениями и системными добавлениями.
Хорошо - достаточно болтаться. Здесь Hello World в MEF и С#. Наслаждайтесь!
using System;
using System.ComponentModel.Composition;
using System.Reflection;
namespace HelloMEF
{
public interface IGreetings
{
void Hello();
}
[Export(typeof(IGreetings))]
public class Greetings : IGreetings
{
public void Hello()
{
Console.WriteLine("Hello world!");
}
}
class HelloMEF : IDisposable
{
private readonly CompositionContainer _container;
[Import(typeof(IGreetings))]
private IGreetings greetings = null;
public HelloMEF()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
}
public void Run()
{
greetings.Hello();
}
public void Dispose()
{
_container.Dispose();
}
static void Main()
{
using (var helloMef = new HelloMEF())
helloMef.Run();
}
}
}
Ответ 3
На вопрос Энди о безопасности для расширений, которые загружаются MEF (извините, у меня пока нет достаточного количества очков:)), место для обращения это находится в Каталоге. Каталоги MEF полностью подключаются, поэтому перед загрузкой вы можете написать собственный каталог, который проверяет ключи сборки и т.д. Вы могли бы даже использовать CAS, если хотите. Мы смотрим, возможно, с помощью крючков, чтобы вы могли сделать это без необходимости писать каталог. Однако источник для текущих каталогов свободно доступен. Я подозреваю, что минимум - это кто-то (может быть, в нашей команде) будет реализовывать его и бросить его в проекте расширения/вклада на CodePlex.
Ответ 4
Утиная печать не будет отправляться в V1, хотя она находится в текущем падении. В будущем случае мы заменим его на переходный механизм, в котором можно зацепить механизм печати утиной. Причина, по которой мы смотрели на утиную печать, - это обращение к сценариям версий. С Duck Typing вы можете удалить общие ссылки между экспортерами и импортерами, тем самым позволяя нескольким версиям контракта жить бок о бок.
Ответ 5
Энди, я считаю, что Glenn Block отвечает на многие из таких естественных вопросов, как эти в этой теме на форуме MSDN MEF:
Сравнение составаContainer с традиционными контейнерами IoC.
В какой-то степени ответ Артема выше правилен относительно первичного замысла MEF, который является расширяемостью, а не композицией. Если вы в первую очередь заинтересованы в композиции, используйте один из других обычных подозреваемых IoC. Если, с другой стороны, вы, в первую очередь, заинтересованы в расширяемости, то введение каталогов, частей, тегов метаданных, утиная печать и отложенная загрузка все делают для некоторых интересных возможностей. Кроме того, Krzysztof Cwalina делает снимок здесь при объяснении того, как MEF и System.Addins связаны друг с другом.
Ответ 6
Айенде также неплохо написана здесь: http://ayende.com/Blog/archive/2008/09/25/the-managed-extensibility-framework.aspx
Ответ 7
Это не инъекция контрольного контейнера. Это плагин поддержки поддержки.
Ответ 8
Я бы сказал, что, учитывая, что он собирается отвиснуть от пространства имен System в платформе .NET 4.0, вы не ошибетесь. Будет интересно посмотреть, как развивается MEF и какое влияние оказывает Hamilton Verissimo (Castle) на направление MEF.
Если он ошеломляет как утку, это может быть частью текущей стаи контейнеров IoC...
Ответ 9
Более подробное обсуждение этого в этом сообщении и комментариях
http://mikehadlow.blogspot.com/2008/09/managed-extensibility-framework-why.html