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

发布于 2024-11-09 02:56:13 字数 1632 浏览 0 评论 0原文

我有以下设置:

  • 一个 Silverlight 应用程序拆分 xaps/modules
  • 我使用MEF作为DI框架来连接 我的应用程序的各个部分。

  • 我有 2 个区域:

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

  • 其中一个(正确的)填充有 包含选项卡控件的视图 我居住的地区(根据 选择哪个客户) 另一个包含选项卡控件的视图 与一个区域。

    右侧结果: 在此处输入图像描述

要填充第一级选项卡控件,我正在监听“客户更改事件”-(这非常有用)当我收到事件时,我用视图填充第一级选项卡区域:

    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 的同一实例?

提前致谢

I have the following setup:

  • An Silverlight app split across
    xaps/modules
  • I use MEF as DI framework to connect
    various parts of my application.

  • I have 2 regions:

  • One (the left one) is populated with
    a list view (e.g. customers)

  • One (the right one) is populated with
    a view containing a tabcontrol with a
    region which I populated (according
    to which customer is selected) with
    another view containin a tab control
    with a region.

    The right side result:
    enter image description here

To populate the first level tabcontrol I am listening to the "customer changed event" - (this works great) and when I get receive the event I populate the First Level tab area with Views:

    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

Note: When creating the FirstLevelView I have to throw in a CompositionInitializer.SatisfyImports call to make sure the FirstLevelView resolves its ViewModel reference.

To get an instance of the EventsAggregator in the SecondLevel ViewModel I use:

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

   End Sub

My problem is that the EventAggregator instance I get in the second level view model is different from the EventAggregator instance in the first level so if I publish DoStuffSecondLevel on the first level it will not be caught in the second level.

Why do I get 2 different instances of the EventAggregator?
What can I do to share the same instance of the EventAggregator across the application?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄意 2024-11-16 02:56:13

问题是 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 的 ExportFactoryComponentInitializer 仅适用于 Silverlight 应用程序(为什么!?)。 Glen Block 创建了一个库,可以访问 System.ComponentModel.Composition.Initialization.dll 库的桌面版本。我尝试使用它,但它失败了,因为在代码中,如果容器已经存在,它就会失败......再说一遍,为什么?我还没有尝试将 MEF2(Codeplex 预览)与此解决方案一起使用,但我认为它会工作得更好(也许)。烦人的部分是,如果您选择使用 MEF2 (Codeplex),则必须重建 Prism 二进制文件,并将 .NET 4 MEF 库的所有引用替换为 Codeplex MEF2 库。这使得 Prism 能够毫无抱怨地使用 Codeplex MEF2 库。我将尝试看看这样做是否可以使该解决方案在 WPF 中可行。

The problem is that the MefBootstrapper creates a Container but does not register it as the DEFAULT container. When SatisfyImports is called, MEF does not see any container, so it creates a new one. That is why the instances are different, because 2 different containers are being created. To solve this, simply set the Prism Container as the default container for MEF to use.

Silverlight Solution (in your bootstrapper):

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

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

    //Etc.
}

WPF (Desktop) Solution:

Currently, I can't get the Desktop solution to work. The problem is that MEF's ExportFactory<T> and ComponentInitializer are only available to Silverlight apps (Why!?). Glen Block created a library that gives access to a desktop version of the System.ComponentModel.Composition.Initialization.dll library. I attempted to use that, but it failed because in the code it is set to fail if a container already exists... again, why? I did not try using MEF2 (Codeplex preview) with this solution yet, but I'd imagine that it would work better (perhaps). The annoying part is that if you choose to use MEF2 (Codeplex) you must rebuild the Prism binaries and replace all references of the .NET 4 MEF library with the Codeplex MEF2 library. That gives Prism the ability to work with the Codeplex MEF2 library without complaining. I will try to see if doing that makes this solution viable with WPF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文