MVVM RI doesn't use library, how come?

Topics: Prism v4 - Silverlight 4
Aug 23, 2010 at 9:06 PM


I found it interesting that the MVVM RI (along with the MVVM quickstarts) doesn't use the Prism library at all: no modules, service locator, region management or event aggregator, and thus no bootstrapper. It uses its own solution for region management of a single region. It also doesn't make use of the Silverlight-specific CompositionInitializer pattern in Silverlight MEF.

Is this the result of a deliberate decision?

Also, out of curiousity - StateManager and ViewFactory in the MVVM RI are app-wide services that use the MEF container. ViewFactory specifically calls out that one of the primary reasons it exists is to avoid composing the container in itself. Is composing an MEF container inside itself considered something of an MEF anti-pattern?


Aug 26, 2010 at 9:05 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Aug 26, 2010 at 9:06 PM
Edited Aug 26, 2010 at 9:07 PM

Hi NW,

Thanks for your feedback, this is really valuable for the product team (I copied this as a workitem). The MVVM RI reference implementation does not make use of the CAL, since it is more focused on providing guidance of the MVVM pattern. But take into account that the prism team has not updated yet the Stock Trader RI. So, this will be probably the application where all the guidance pieces come together.

Regarding to the StateHandler and the ViewFactory are helpers that are useful for managing objects registered in the container. They are registered in the container, so it makes them available to be imported. The following piece code of the Application_Startup method in App.xaml.cs shows how they are registered:

// Register services needing container explicitly
this.container.ComposeExportedValue<ViewFactory>(new ViewFactory(this.container));
this.container.ComposeExportedValue<StateHandler>(new StateHandler(this.container));

This way, when any of them are imported, it is not necessary to resolve the container.

Please let me know if this helps. 

Fernando Antivero

Aug 27, 2010 at 5:11 PM
Edited Aug 27, 2010 at 5:17 PM

Hi Fernando,

Thanks for the reply. Really looking forward to seeing what shows up in the coming months.

I don't want to get too far off track from the topic of this thread, but to continue the sidebar conversation regarding ViewFactory: part of your answer is "this way... it is not necessary to resolve the container." The core of my question was "why not just resolve the container?"

I did some reading (specifically this and this, which I found via the link from the bottom of the MEF documentation about ExportFactory), and I think I have a better understanding of why it makes sense not to access the container directly, but moving it off into the ViewFactory service seems like it just moves the problem. It seems like ExportFactory or Lazy can be used to solve this in a cleaner way. By using ExportFactory or Lazy, the entire application can live "in the container", as the second article puts it, as opposed to having services like ViewFactory have to carry around a reference to it. The metadata functionality gives the added bonus of not having to register contract names that correspond to the view name - it can go in the metadata instead. If you use ExportFactory, you can also maintain control over lifetimes and destroy views when you're done with them.

In SingleViewUIService.cs, instead of this:

public ViewFactory ViewFactory { get; set; }

public void ShowView(string viewName)
    var view = this.ViewFactory.GetView(viewName);
    this.MainWindow.CurrentView = view;

You can have something like this:

public IEnumerable<ExportFactory<UserControl, IDictionary<string, object>>> Views;

public void ShowView(string viewName)
    var view = Views.Single(v => ((string)v.Metadata["ViewName"]) == viewName).CreateExport();
    this.MainWindow.CurrentView = view.Value;

Here, I'm just using weakly-typed metadata and I'm not taking advantage of the fact that I can dispose of views (I could have just used Lazy), but ViewFactory and it's container reference is no longer needed, and instead of registering views using the friendly view name as the contract, I can put that information in the metadata, which is probably better suited for it.

Let me know if this is off base, as I'm just now getting my head around these concepts, but this seems like a good opportunity to insert this pattern into a quickstart/RI.