I have the following setup:
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With