fix: SatisfyImports not working correctly in Prism over MEF

4 בפברואר 2011

אין תגובות

I’m working on a Silverlight project under Prism/MEF, and that’s the first time I’m using MEF and not Unity in Prism. Resolving dependencies works a bit differently with MEF, and so when I tried to resolve IRegionManager in a ViewModel class my first instinct was to do the following:

   1: [Import]

   2: public IRegionManager regionManager;

   3:  

   4: public ViewModelConstructor()

   5: {

   6:     CompositionInitializer.SatisfyImports(this);

   7: }

I’m creating my view models using the ViewModelLocator pattern (and not directly using MEF) since IMO it’s a much better approach. (More on that on a later post)

At first it seemed like it was working, and that MEF was actually supplying me with the region manager, only… the Navigation didn’t work. It took me a few minutes to realize that the problem was not of the RegionManager (As there are so many things that can get wrong there…), but it was actually MEF’s doing.

Turns out that the region manager I was getting was a brand new instance, and not the instance that the MefBootstrapper created.. and that was because the underlying IOC Container in MEF was actually not the same.

MefBootstrapper creates a MEF Container, but, for some reason doesn’t register it as the default one. When I later do SatisfyImports, MEF doesn’t know of any container, and thus creates a new container => and a new RegionManager if I ask it of one.

The solution is rather simple, all you have to do is to add the following to the to the method InitializeShell in the bootstrapper:

   1: protected override void InitializeShell()

   2: {

   3:     base.InitializeShell();

   4:  

   5:     // The added line. Why this is not part of Prism's documentation is really beyond me :-/

   6:     CompositionHost.Initialize(this.Container);

   7:  

   8:     Application.Current.RootVisual = (UIElement)this.Shell;

   9: }

and voila, it’s working as expected.

CompositionHost.Initialize(..) registers the IOC container to use if you later do CompositionInitilizer.SatisfyImports().

I can’t really understand why MEF is using two different classes here. CompositionHost != CompositionInitializer. It seems like really bad design, but that’s just the way it is.

I’d expect this line to already be in Prisms documentation and in the Quick Starts, but it’s not.

 

and of course, kudos to the MEF master, Bnaya Eshet for helping me in tracking the issue Smile

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *