У меня есть сценарий с приложением WPF, в котором размещаются некоторые представления (пользовательские элементы управления) со своими моделями представления, которые обнаруживаются в виде экспортируемых деталей MEF в папке плагинов.Приложение загружает свои данные вместе с файлом конфигурации, в котором также указывается, какие детали следует импортировать среди доступных.
Первый вопрос относится к загрузчику MEF: как я могу настроить его, чтобы он знал о папке плагинов?Я знаю о его SelectAssemblies переопределении, но он требует сборок, в то время как мой типичный подход - каталог каталогов MEF.Я не хотел бы использовать методы, такие как Assembly.LoadFrom для каждой библиотеки DLL, найденной в каталоге: для этого есть MEF (управление временем жизни и тому подобное).Итак, как я могу сделать что-то похожее на MEF AggregateCatalog , построенный из DirectoryCatalog в загрузчике?
Второй вопрос : раз у меня естьсписок виртуальных машин мне нужен, я хочу их создать.Некоторые из них требуют внедрения служб CM, таких как IEventAggregator или IWindowManager , так что они имеют соответствующий конструктор импорта, и поэтому мне требуется, чтобы CM создал их для меня: но мне нужно сделатьэто программно, поэтому я не могу просто использовать атрибут Import для свойства или импортирующего конструктора.
То же самое верно и для представлений: после того, как у меня есть виртуальные машины, мне нужен CM для их создания и установкисоответствующая виртуальная машина как их контекст данных;но я не могу использовать диспетчер окон, потому что я просто хочу получить их, а затем программно добавить их (они являются пользовательскими) в элемент управления с вкладками, который составляется по-разному в зависимости от конфигурации данных.
I'mиспользование MEF, потому что приложение ориентировано на плагины, и поэтому я могу придерживаться его ограничений при использовании в качестве IoC.Но я хотел бы использовать CM для создания экземпляров моих представлений и моделей представления (все они содержатся в нескольких библиотеках подключаемых модулей) и правильно связывать их.Может ли кто-нибудь дать некоторые подсказки или указать образцы или документацию по этому поводу?
Второе обновление , как и было обещано:):
Я, по сути, следую этим шагам:
создать (используя MEF) необходимые виртуальные машины в соответствии с некоторой логикой приложения.Все виртуальные машины являются экспортом MEF, размещенным в нескольких плагинах в папке плагинов.
для каждой виртуальной машины, вызов:
static private object LocateViewFor(object viewmodel)
{
UIElement view = ViewLocator.LocateForModel(viewmodel, null, null);
ViewModelBinder.Bind(viewmodel, view, null);
return view;
}
Thisдолжен istantiate мои представления через CM, который также удовлетворит их импорт и свяжет каждое представление с его VM.Используется «стандартный» MefBootstrapper, модифицированный для WPF (см., Например, здесь ).В любом случае, это не работает и возвращает ноль.
Я должен сообщить загрузчику, где он может найти мой экспорт MEF.Они находятся в папке плагинов, и если бы я не использовал CM, я бы использовал MEF DirectoryCatalog для проверки его содержимого.Типичной точкой расширения для загрузчиков в CM является переопределение SelectAssemblies, которое требует от меня вернуть список объектов Assembly.Загрузка всех сборок из папки не вариант.Следуя предложению на приведенной выше странице, я мог бы сделать что-то вроде добавления метода в моем загрузчике:
private IEnumerable GetDirectoryCatalogs()
{
return new ComposablePartCatalog[]
{
new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)
// TODO other plugins folders...
};
}
И изменить его конфигурационный код следующим образом:
_container = new CompositionContainer(
new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType()
.Union(GetDirectoryCatalogs())));
Это эффективноКажется, что загружает необходимые сборки, как для MEF, но недостаточно «зарегистрировать» их в CM AssemblySource.Instance: фактически, я могу получить виртуальные машины через MEF, но когда я прошу CM получить соответствующее представление (либо с помощьюПриведенный выше метод или вызов IWindowManager.ShowDialog (myviewmodel, null)) Я получаю значение null из метода или (для второго примера) текстовое поле «placeholder», в котором говорится, что представление для моей виртуальной машины не может быть найдено.
Похоже, это связано с тем, что представление, как и модель представления, размещено в другой сборке, моем плагине MEF.Я гарантировал, что и представление, и модель представления совместно используют одно и то же пространство имен , а следуют соглашению об именовании типа SomeNamespace.SampleViewModel - SomeNamespace.SampleView;Кроме того, и представление, и модель представления экспортируются путем их украшения с помощью [Export] и являются производными от общих интерфейсов.Тем не менее, я не могу заставить CM работать должным образом при работе с внешними сборками.MEF работает нормально, со всеми его импортом и экспортом, но как только CM вводит уравнение, он не может сделать свое «волшебство» и найти представление из VM.
Любая подсказка?