этот пост в идеале продолжает мой другой пост о плагинах MEF, но мой первый пост был слишком полон комментариев, и этот пример более полный.Здесь я суммирую мой обновленный сценарий, со всеми моими выводами до этого момента.Надеюсь, что это может быть полезно для других новичков CM, таких как я.
Вы можете загрузить полный пример сценария воспроизведения: это почти тупой скелет для приложения на основе плагинов CM + MEF:
VS2010 repro solution (обновлено)
Это минимальное урезанное решение, представляющее мои проблемы с CM + MEF.Существует 3 проекта:
- основной пользовательский интерфейс (CmRepro).
- основная DLL, общая для всех надстроек (AddinCore), с парой интерфейсов и пользовательских атрибутов, используемых для MEFметаданные.
- образец DLL-надстройки (AlphaAddin) с представлением и моделью представления, реализующей интерфейсы.
* ядро содержит 2 интерфейса, представляющих модель представления иего вид и 2 атрибута, которые будут использоваться для украшения моделей и видов.Интерфейс viewmodel описывает класс, который должен составлять приветственное сообщение от имени какого-то человека, поэтому он предоставляет несколько свойств и метод для этого.Интерфейс представления просто предоставляет свойство, возвращающее его приведение DataContext к интерфейсу viewmodel.
Пример addin имеет реализацию для viewmodel и представления;оба являются MEF-экспортами, оформленными соответствующим атрибутом.В реальном решении несколько свойств этих атрибутов используются для фильтрации;здесь у меня просто есть фиктивное свойство Language , которое должно допускать использование других плагинов для разных языков.
Основной пользовательский интерфейс имеет загрузчик MEF, который добавляет код для получения экспорта MEFиз папки надстроек.Я изменил этот код, чтобы включить экспорт из каталогов MEF и получить лучшее представление о некоторых исключениях MEF, но все же я не могу понять, как правильно «зарегистрировать» их в CM.
Основная модель представления имеет 2 методы : one (A) использует каталог MEF для извлечения модели представления и ее вида, связывания их и отображения в окне.Другой (B) использует тот же каталог для получения модели представления, а затем менеджер окон CM для определения местоположения, создания, привязки и отображения соответствующего представления в соответствии с соглашениями об именах CM.Эти методы представляют два альтернативных способа, с которыми мне приходится иметь дело в моем реальном коде, то есть создание экземпляров некоторых критически важных объектов "самостоятельно", просто используя MEF, но затем позволяя им работать для CM, или позволяя CM (с MEF-загрузчиком) выполнять большую частьработа начинается с viewmodel.
Во всяком случае кажется, что в обоих случаях мне не хватает чего-то, что касается регистрации в CM.Проблемы:
(A) как подключить VM + V для CM, чтобы применялись соглашения для привязки данных и т. Д.?В настоящее время я могу собрать свои части MEF вместе, но CM игнорирует их, поскольку он не использовался для создания экземпляров ни одной из них. Я отвечаю себе здесь :
<code>ViewModelBinder.Bind(viewmodel, (UserControl)view, null);
(B) как мне зарегистрировать экспорт из MEF в CM такчто диспетчер окон CM может найти представление?В настоящее время не удается найти представление из модели представления.
Добавление (21 июня)
Я пытаюсь объяснить лучше, для кого нет доступа к репро-решению.Я использую «стандартный» загрузчик MEF, изменяя переопределение Configure следующим образом:
_container = new CompositionContainer(
new AggregateCatalog(AssemblySource.Instance.Select(
x => new AssemblyCatalog(x)).OfType()
.Union(GetAddinDirectoryCatalogs())));
, это создает контейнер композиции MEF, который объединяет каталог из AssemblySource с типами CM, такими как агрегатор событий или менеджер окон, с каталогомиз нескольких каталогов надстроек, которые содержат экспорты как для V, так и для виртуальных машин.
В моей основной модели основного вида я создаю новую виртуальную машину из плагина, найденного в каталоге приложения хоста среди других, и мне нужен CMоконный менеджер для поиска, создания и отображения своего представления в диалоговом окне, например:
viewmodel = GetMyViewModelFromAddin();
windowmanager.ShowDialog(viewmodel);
CM в любом случае не может найти вид. AFAIK, соглашения об именах соблюдаются: и V, и VM находятся в одной сборке надстройки, помеченной как экспорт MEF, названной как SomethingViewModel / SomethingView. В любом случае, как указал Лиф в своем разъяснении, AssemblySource.Instance - это статическая коллекция сборок IObservableCollection, и я не добавил в нее свои надстройки. Но суть в том, что я не хотел бы добавлять их все заранее, потому что это означает загрузку ВСЕХ надстроек, еще не зная, какие (если они есть) будут когда-либо использоваться. Надежная система плагинов является причиной использования MEF, в конце концов. Я новичок в CM и не уверен, возможно ли (и где) найти точку расширения для CM в этом сценарии. Диспетчер окон вообще не вызывает мою реализацию загрузчика, очевидно, потому что IoC не создает экземпляров, так как в экземпляре исходного кода не найдено ни одного совпадения. Так что, похоже, я застрял здесь, единственное решение заключается в предварительной загрузке всех сборок в Экземпляре, но это, похоже, наносит ущерб всей цели использования MEF.
Приложение на основе плагинов, которое я разрабатываю, загружает тонны «пар» V + VM CM, представляющих виджеты пользовательского интерфейса, которые, в свою очередь, часто используют диспетчер окон для вызова других пар V + VM в качестве диалогов. Я могу обойти создание экземпляров с помощью CM и использовать MEF для извлечения V + VM для каждого виджета, но все же я сталкиваюсь с той же проблемой местоположения вида для каждого виджета, для которого требуется оконный менеджер. Другой альтернативный (обходной путь), который я вижу, - это избегать использования оконного менеджера и реализовывать свой собственный механизм для показа диалогов из виджетов, но это заставляет меня немного ошибаться в CM ... :). Обычно, когда я пишу гораздо больше кода, чем ожидалось, я склонен думать, что я неправильно использую инструмент. Есть идеи?