Prism:EventAggregator和MEF - EventAggregator的2个不同实例

时间:2011-05-19 12:42:10

标签: .net silverlight prism mef eventaggregator

我有以下设置:

  • Silverlight应用程序分开 xaps /模块
  • 我使用MEF作为DI框架进行连接 我申请的各个部分。

  • 我有两个地区:

  • 填充一个(左侧) 列表视图(例如客户)

  • 填充一个(右侧) 包含tabcontrol的视图 我居住的地区(根据 选择哪个客户) 另一个视图包含选项卡控件 与一个地区。

    右侧结果: 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引用。

要在SecondLevel 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实例?

提前致谢

1 个答案:

答案 0 :(得分:3)

问题是MefBootstrapper创建了一个Container,但没有将它注册为DEFAULT容器。当调用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应用(为什么!?)。 Glen Block创建了一个库,可以访问System.ComponentModel.Composition.Initialization.dll库的桌面版本。我试图使用它,但它失败了,因为在代码中,如果容器已经存在则设置为失败...再次,为什么?我没有尝试使用MEF2(Codeplex预览版)和这个解决方案,但我想它会更好(也许)。令人讨厌的部分是,如果您选择使用MEF2(Codeplex),您必须重建Prism二进制文件并用Codeplex MEF2库替换.NET 4 MEF库的所有引用。这使得Prism能够在没有抱怨的情况下使用Codeplex MEF2库。我将尝试看看是否这样做使得这个解决方案适用于WPF。