Является ли MEF делом "все или ничего"? - PullRequest
2 голосов
/ 20 апреля 2010

Недавно у меня было несколько вопросов о MEF, но вот главный вопрос - действительно ли это все или ничего, как кажется?

Моя базовая структура приложения - это просто приложение, несколько общих библиотек, которые должны быть синглетонами, и несколько разных плагинов (которые могут реализовывать разные интерфейсы). Приложение загружает плагины, и как приложению, так и всем плагинам требуется доступ к общим библиотекам.

Мой первый опыт работы в MEF был довольно успешным, хотя я на этом пути допустил несколько глупых ошибок, потому что пробовал так много разных вещей, но иногда я просто запутывался. Но в конце прошлой ночью я запустил небольшое тестовое приложение с MEF, некоторыми общими библиотеками и одним плагином.

Теперь я перехожу к целевому приложению, которое я уже описал. И эта часть с несколькими плагинами немного беспокоит.

Мое существующее приложение уже поддерживает несколько плагинов с разными интерфейсами с помощью Reflection. Мне нужно иметь возможность уникально идентифицировать каждый плагин, чтобы пользователь мог выбрать один и получить ожидаемое поведение этого плагина. Проблема в том, что я пока не знаю, как это сделать ... но это тема другого вопроса.

В идеале я мог бы взять свой существующий загрузчик плагинов и использовать его как есть, полагаясь на MEF для разрешения общей библиотеки. Проблема в том, что я не могу заставить MEF загрузить их (т.е. я получаю CompositionException при вызове ComposeParts ()), если только я не использую MEF для загрузки плагина. И если я сделаю это, ну ... тогда мне нужно знать, как отслеживать их по мере их загрузки, чтобы пользователь мог выбрать один из списка плагинов.

Каков ваш опыт в попытках смешать и сопоставить эти подходы?

1 Ответ

4 голосов
/ 21 апреля 2010

MEF позволяет легко загружать сборки плагинов. Если у вас есть контроль над плагинами (я имею в виду, что вы можете добавить атрибуты экспорта MEF), то нет необходимости сохранять свой собственный загрузчик плагинов, который использует отражение. MEF сделает все это за вас.

При этом "смешивание и сопоставление" MEF с другими технологиями, безусловно, возможно. Похоже, ваша проблема в том, что если вы используете свой собственный загрузчик плагинов, вы не добавляете эти плагины в контейнер MEF. В результате вы получаете CompositionException для деталей, которые пытаются импортировать выбранный плагин.

Чтобы добавить плагин, который вы загрузили с собственным кодом в контейнер MEF, вы можете использовать ComposeExportedValue, например:

container.ComposeExportedValue<IPlugin>(selectedPlugin);

edit: Я понимаю, что вы сейчас имеете в виду под "все или ничего". Ваша проблема в том, что для того, чтобы иметь возможность импортировать детали с помощью MEF, вам также необходимо создать объект с помощью MEF. Затем эта проблема распространяется на объект, который обычно создает этот объект, и т. Д. Вплоть до корня приложения.

Чтобы избежать этого эффекта «все или ничего», вы можете пойти на компромисс, представив контейнер MEF как глобальную переменную (то есть статическое поле). Таким образом, классы могут обращаться к контейнеру MEF и извлекать из него экспорт, например, вызвав Program.Container.GetExportedValue<MyDependency>() в конструкторе.

edit2 : Если у вас есть объект, который не был сконструирован MEF, есть два способа добавить его в контейнер.

Первый - позвонить container.ComposeExportedValue<IMyContractType>(myObject);.

Второй - вернуть объект в метод получения свойства, а затем пометить само свойство атрибутом [Export (typeof (SomeType))].

...