Prism:EventAggregator 和 MEF - EventAggregator 的 2 个不同实例
我有以下设置:
- 一个 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:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是 MefBootstrapper 创建了一个 Container,但没有将其注册为 DEFAULT 容器。当调用 SatisfyImports 时,MEF 没有看到任何容器,因此它创建一个新容器。这就是实例不同的原因,因为正在创建 2 个不同的容器。要解决此问题,只需将 Prism 容器设置为 MEF 使用的默认容器即可。
Silverlight 解决方案(在您的引导程序中):
WPF(桌面)解决方案:
目前,我无法使桌面解决方案正常工作。问题是 MEF 的
ExportFactory
和ComponentInitializer
仅适用于 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):
WPF (Desktop) Solution:
Currently, I can't get the Desktop solution to work. The problem is that MEF's
ExportFactory<T>
andComponentInitializer
are only available to Silverlight apps (Why!?). Glen Block created a library that gives access to a desktop version of theSystem.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.