Prism: EventAggregator и MEF - 2 разных экземпляра EventAggregator - PullRequest
5 голосов
/ 19 мая 2011

У меня есть следующие настройки:

  • Приложение Silverlight разделено на xaps / modules
  • Я использую MEF в качестве инфраструктуры DI для подключения различных частей моего приложения.

  • У меня есть 2 региона:

  • Одна (левая) заполняется списком (например, клиенты)

  • Один (правый) заполняется представлением, содержащим элемент управления табуляции с областью, которую я заполнил (в соответствии с выбранным клиентом), другим представлением, содержащим элемент управления вкладкой с регионом.

    Результат справа: enter image description here

Чтобы заполнить tabcontrol первого уровня, я слушаю «событие, измененное клиентом» - (это прекрасно работает), и когда я получаю событие полученоЯ заполняю область вкладки «Первый уровень» представлениями:

    Dim lReg As IRegion = Me.mRegionManager.Regions("FirstLevelTabReqion")
    Dim lViewID As String = CommonDefinitions.Constants.BuildFirstLevelViewName(lUniqueID)
    Dim lFirstLevelView FirstLevelView = TryCast(lReg.GetView(lRqViewID), FirstLevelView)
    If lFirstLevelView Is Nothing Then     
         lFirstLevelView = New FirstLevelView()
         Dim lRegMan1 As IRegionManager = lReg.Add(lFirstLevelView, lViewID, True)
         lFirstLevelView.SetRegionManager(lRegMan1)
         ...
    End If

Примечание: При создании FirstLevelView мне нужно добавить вызов CompositionInitializer.SatisfyImports, чтобы убедиться, что FirstLevelView разрешает свою ссылку ViewModel.

Чтобы получить экземпляр tEventsAggregator во второй модели ViewLevel, которую я использую:

  <ImportingConstructor()>
  Public Sub New(ByVal iEvAggregator As IEventAggregator)
          EventAggregator = iEvAggregator
          EventAggregator.GetEvent(Of DoStuffSecondLevel).Subscribe(AddressOf OnDoStuffSecondLevel, True)

   End Sub

Моя проблема в том, что экземпляр EventAggregator, который я получаю в модели представления второго уровня, отличается от экземпляра EventAggregator на первом уровне, поэтому, если я опубликую DoStuffSecondLevel наПервый уровень не будет перехвачен на втором уровне.

Почему я получаю 2 разных экземпляра EventAggregator?
Что я могу сделать, чтобы использовать один и тот же экземпляр EventAggregator в приложении?

Заранее спасибо

1 Ответ

3 голосов
/ 06 июля 2011

Проблема в том, что MefBootstrapper создает контейнер, но не регистрирует его как контейнер DEFAULT. Когда вызывается SatisfyImports, MEF не видит ни одного контейнера, поэтому создает новый. Вот почему экземпляры разные, потому что создаются 2 разных контейнера. Чтобы решить эту проблему, просто установите Prism Container в качестве контейнера по умолчанию для использования MEF.

Решение Silverlight (в вашем загрузчике):

protected override void InitializeShell()
{
    base.InitializeShell();

    //Make the container the default one.
    CompositionHost.Initialize(this.Container);

    //Etc.
}

WPF (Desktop) Решение:

В настоящее время я не могу заставить работать настольное решение. Проблема в том, что MEF ExportFactory<T> и ComponentInitializer доступны только для приложений Silverlight (Почему !?). Глен Блок создал библиотеку, которая предоставляет доступ к настольной версии библиотеки System.ComponentModel.Composition.Initialization.dll. Я пытался использовать это, но это не удалось, потому что в коде он настроен на неудачу, если контейнер уже существует ... опять же, почему? Я еще не пробовал использовать MEF2 (предварительный просмотр Codeplex) с этим решением, но думаю, что оно будет работать лучше (возможно). Раздражает то, что если вы решите использовать MEF2 (Codeplex), вы должны перестроить двоичные файлы Prism и заменить все ссылки на библиотеку .NET 4 MEF библиотекой Codeplex MEF2. Это дает Prism возможность работать с библиотекой Codeplex MEF2 без каких-либо жалоб. Я постараюсь выяснить, делает ли это решение жизнеспособным с WPF.

...