2011-05-19 162 views
5
的2個不同的實例

我具有以下設置:棱鏡:EventAggregator和MEF - EventAggregator

  • 跨越 xaps /模塊的Silverlight應用程序分割
  • 我使用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引用。

要獲得EventsAggregator的一個實例,在第二級別視圖模型我用:

<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實例?

在此先感謝

+0

我想補充一點,我遇到了同樣的問題。我想要一個解決方案,使用ComponentInitializer.SatisfyImports(this);我使用ComponentInitializer.SatisfyImports(...)',以便我可以new()我的其他ViewModels(所以我不用不必手動重置他們的狀態),這導致我使用SatisfyImports,因此我可以獲得我的服務,主要是EventAggregator。 – michael 2011-06-30 15:22:03

+0

請檢查以下幾點:1.在配置MEF容器時,是否將CreationPolicy.NonShared的默認創建策略設置爲? 2.你的EventAggregator類是否有PartCreationPolicy屬性? 3.是否有可能爲SecondLevelViewModel創建單獨的CompositionContainer對象? – 2011-07-01 07:21:02

回答

3

的問題是,MefBootstrapper創建了一個集裝箱,但不註冊爲默認容器。當調用SatisfyImports時,MEF不會看到任何容器,因此會創建一個新容器。這就是實例不同的原因,因爲正在創建2個不同的容器。爲了解決這個問題,只需將Prism容器設置爲MEF使用的默認容器即可。

的Silverlight解決方案(在你的引導程序):

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

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

    //Etc. 
} 

WPF(桌面)解決方案:

目前,我不能拿到桌面解決方案正常工作。問題是MEF的ExportFactory<T>ComponentInitializer僅適用於Silverlight應用程序(Why !?)。Glen Block創建了一個可訪問桌面版System.ComponentModel.Composition.Initialization.dll庫的庫。我試圖使用它,但它失敗了,因爲在代碼中,如果一個容器已經存在,它會被設置爲失敗......爲什麼?我沒有嘗試用這個解決方案使用MEF2(Codeplex預覽版),但我想可能會更好(也許)。煩人的部分是,如果您選擇使用MEF2(Codeplex),則必須重新構建Prism二進制文件,並用Codeplex MEF2庫替換.NET 4 MEF庫的所有引用。這讓Prism能夠與Codeplex MEF2庫一起工作而不抱怨。我會試着看看這樣做是否可以使WPF成爲可行的解決方案。

+0

sliverlight部分效果很好。我希望你可以讓WPF的一部分工作。 – michael 2011-07-06 18:25:51

+0

@ m-y任何運氣得到這個工作? – 2012-04-11 14:49:13

+0

@BahriGungor:我有點不爽,通過用MEF2(Codeplex)庫替換System.ComponentModel引用,然後重新編譯解決方案,我得到了Prism(Desktop)進行編譯。我想這包括在我的WPF應用程序中,並引用了MEF2(Codeplex)庫而不是.NET 4 MEF。它允許我使用'ExportFactor ',但SatisfyImports仍然有點bug。 – 2012-04-11 16:57:34