Partilhar via


Prism and MEF

One of the most highly anticipated of the new technologies coming in .NET 4.0 and Silverlight 4.0 is the Managed Extensibility Framework (MEF). Folks that are familiar with Prism and that have been looking at MEF have been wondering how Prism and MEF relate to each other. At a high level, MEF shares some of the same goals as Prism in terms of supporting easy to extend applications, and this has led to a lot of questions on how MEF and Prism relate to each other and about the future direction of Prism once MEF is released next year. Hopefully this post will go a long to clearing up the confusion and give you a sense of how we think Prism and MEF will work together.

First of all, it’s important to note that Prism and MEF are very much complementary technologies. MEF allows you to create extensible applications by providing support for automatic component discovery and composition. It does not focus on application- or UI-level patterns or on any specific UI technology. Prism on the other hand provides support for creating modular composite client applications built on Silverlight and/or WPF. As such it supports a wide range of patterns including the higher level UI patterns and concepts that are need to support composite clients – such as modularity, module deployment, loosely coupled communication, commanding, and separated presentation patterns such as Model-View-ViewModel, etc.

There is clearly some overlap between MEF and Prism (since modular composite client applications are by definition extensible!!) but MEF by itself in no way replaces or obviates the need for Prism – they are each targeted at different parts of the overall puzzle. MEF in fact is fantastic news for Prism, because it means that we can now leverage core capabilities that are provided by the .NET Framework, whereas in the past we’ve had to build those capabilities as part of Prism itself.

Prism 4.0

In the next version of Prism (Prism 4.0) we’ll be focusing on leveraging MEF as much as possible and ensuring that Prism and MEF work seamlessly together. We’ll be kicking off the Prism 4.0 project early next year and, as always, we’ll be providing drops every two weeks during development so you’ll be able to provide feedback and direct the scope and focus of the project as we go. But since MEF integration is likely be one of the first things that we’ll tackle, I think it’s worth describing our current thinking on how we think Prism can leverage MEF and how they can complement each other so that you can provide feedback to us before we start. In the rest of this post I’ll outline a couple of the areas where I think MEF and Prism can be closely integrated. Let me know what you think.

Component Composition

Firstly, let’s talk about component composition. Prism uses the Dependency Injection pattern (DI) quite extensively because it helps to maintain loose coupling between the various components in an application. I’m not going to get into the “is MEF a DI container or isn’t it” discussion here :-) but suffice it to say that there are similarities and differences between the way MEF works and the way that typical Dependency Injection containers work. The upshot is that there are things that MEF does well and there are things that DI containers do well, but the important thing is that both MEF and DI containers promote loose coupling between components, which is a very good thing.

In the Prism 2.0 Quick Starts and the Reference Implementation we use the Unity Application Block as our DI container of choice. However, it’s important to note that the Prism code libraries themselves do NOT depend explicitly on Unity, or in fact on any specific DI container implementation. This is an important point. It was an explicit design decision to allow the use of any other DI container (such as CastleWindsor, StructureMap, AutoFac, Ninject, etc) or the use of any other kind of component composition strategy that suites your needs – such as the component composition strategy supported by MEF!

So the design of Prism allows you to use MEF with Prism 2.0 today, even though Prism 2.0 was shipped early this year way before MEF was broadly available. It’s pretty easy to use MEF instead of a DI container within a Prism module to help you wire up Views, ViewModels, Controllers, or Presenters, or to get references to EventAggregator or RegionManager instances provided by the Shell. In fact, using MEF like this can actually simplify the code somewhat since it can automatically discover available types without you having to register them explicitly with the DI container. You can also use MEF’s meta-data support to do conditional component composition. We’ll be exploring and providing guidance for these scenarios in Prism 4.0.

Another interesting possibility is to use both MEF and a DI container together in the same application. There are some advantages to this since it allows you to leverage the strengths of each in various situations. In fact, Unity 2.0 (which is currently in development as part of EntLib 5.0) will support the hybrid use of MEF and a DI container and make it seamless and straightforward. In Prism 4.0, we’ll be exploring and providing guidance for the use of MEF + DI container hybrid approaches in the context of composite client application development.

Catalogs and Modules

The use of MEF and/or DI container to help with component composition is pretty straightforward, and largely independent of the higher level constructs and patterns in Prism. But one area where the overlap between MEF and these higher level Prism concepts is not quite as clear cut is in the area of Catalogs and Modules. This area has caused some confusion in part because of overlapping terminology and, in some cases, because of the similar concepts applied at different levels of granularity.

To recap, Prism uses the notion of a module to represent a collection of features, components, and resources that make up a functional unit within the application. Prism modules can be developed, tested and deployed independently. They frequently consist of multiple assemblies and other resources packaged up into an easily deployable unit (for example in a XAP file). Prism provides infrastructure for the flexible deployment of modules. In the case of Silverlight, for example, modules can be downloaded with the core application, or can be downloaded in the background or on-demand.

Prism applications use a module catalog to tell it which modules to load. Module catalogs can be static (i.e. the list of modules is predetermined before run-time) or dynamic (i.e. the list of modules is determined at run-time and can take into account the user’s ID, role, configuration, installed modules, wind direction, etc). Dynamic module catalogs can be used to extend an application after its initial deployment. They can be implemented in many different ways. For example, you can build a dynamic catalog by reading a (local or remote) config file, or by using a web service that specifies the modules to load, or by scanning a particular folder to see what modules have been installed.

Once a module is loaded, Prism looks for an entry type that supports the IModule interface. This interface has only one method – Initialize – and can be used to provide any initialization logic that the module provides. Typically, this method is used to register types within the module with the DI container so that they can be accessed by other modules and the shell. Another common use of this method is to register Views contained within the module with UI regions. The module can do anything it needs to though, including kicking off background threads, making web service calls or downloading additional data or resources. Of course, you don’t have to provide any initialization logic if your module doesn’t require it.

Now, MEF too has the concept of a component catalog. When you import a type in MEF (i.e. you’ve expressed a dependency in one class to another class of a certain type), its resolves that type by looking in the MEF catalog which defines all of the types that are available for export (i.e. types that can be used by MEF to satisfy imports). This is a very powerful feature of MEF and allows you to express dependencies between components and have them fulfilled for you pretty much automatically, without having to explicitly register types with a DI container or having to resort to closely-coupled techniques like ‘new’ or CreateInstance. Note, I say ‘type’ here to keep things simple but MEF generalizes the relationship between importer and exporter using contracts, but contracts most often equate to types, and types can be interfaces.

So Prism module catalogs are really not the same as MEF catalogs since they’re specifying things at completely different levels of granularity. In addition, MEF does not provide any support for the packaging or conditional deployment of functional units within an application. However, there is clearly some overlap here since, at a lower level, Prism modules essentially contain a bunch of components that can import and export types so that they can be hooked up to components from other modules or the shell.

You can imagine using both Prism module catalogs and MEF catalogs together. The key here I think is for Prism to focus on the packaging, deployment and activation of coarse grained functional units (modules), as defined by either a static or dynamic module catalog, and to use MEF to support the flexible, meta-data driven composition of components within and across modules and the shell.

For example, imagine using Prism to build modules that represent functional units within an application and having it take care of their packaging and deployment via a dynamic or static module catalog. As each Prism module is loaded, the component dependencies within it (i.e. imports and exports) can be made available to MEF for component composition. In a sense, each module represents a catalog of components that MEF can use to fulfill and resolve component dependencies. There are other possibilities I am sure, and we’ll be exploring these as part of Prism 4.0…

Prism 4.0 Needs You!

Our goal for Prism 4.0 is to leverage MEF, and other .NET 4.0 and Silverlight 4.0 features, as much as possible so that we can provide a flexible and powerful environment for building modular, composite client applications on WPF and Silverlight 4.0. MEF is an exciting new technology and it’s great to see some level of support for loosely coupled component composition finally make it into the .NET Framework. I’m looking forward to exploring the possibilities here and I think it’s going to be pretty cool…

As well as MEF integration, for Prism 4.0 we’re looking at also providing more guidance on the ViewModel pattern, navigation, out of browser applications, developer/designer workflow, user experience patterns, visual studio templates, and a whole host of other areas. Which ones we tackle will depend on you, so as always, if you have any ideas or feedback, please let us know!

Comments

  • Anonymous
    December 08, 2009
    As you continue to enhance Prism I hope the team won't lose sight of the need to keep the framework footprint small and make it easy to understand and use.

  • Anonymous
    December 09, 2009
    Absolutely Terry, on both counts. A benefit of leveraging features in the platform is that we can remove stuff from Prism, to either make it smaller or make room for more Prism features. Our goal is to keep the size of Prism about the same as it is today though. We're also looking at simplifying some of the more complex areas in Prism and providing more in the way of Visual Studio templates to make development easier and faster.

  • Anonymous
    December 09, 2009
    Nice post David. We're excited to see several p&p deliverables integrating/supporting MEF where appropriate. We look forward to the possibilities! Thanks Glenn

  • Anonymous
    January 01, 2010
    The comment has been removed

  • Anonymous
    January 01, 2010
    David, Why are there so many different directions Microsoft is pushing for WCFSilverlight Business Applications? Why is there a Silverlight Business Application project type in Visual Studio 2010 with absolutly no talk of the Prism project, yet it uses a View-Model-ModelView? We need to be given better direction as to where Microsoft is going with its overall P&P's so we know with certainty a direction to go in. I work for a large oil & gas producer; 3 different developers I work with looked at Prism and "ran for the hills"! I think Microsoft needs to understand that us developers that are swamped with our day to day activities find Prism overwhelming, one of our top project managers commented that these things only work well "in a vaccuum" (not in the real world). Our architects have not yet suggested the use composite applications (yet we have more than 1500 apps company wide and over 8000 employees). I am unsure of using Prism, as I prefer the WCF RIA LOB App's simplicity. I guess I must wait for Prism v4 to decide if I should look in that direction again because the whole Enterprise Libray thing is just too darn bloated. Jason

  • Anonymous
    January 04, 2010
    The comment has been removed

  • Anonymous
    January 19, 2010
    The comment has been removed

  • Anonymous
    January 20, 2010
    The comment has been removed

  • Anonymous
    January 29, 2010
    Really, the only thing that gets me down about CAB/CAL/PRISM is the fact that a Module has to know everything about the Shell in order to integrate correctly into it.  What I mean is that we need a better way for the "shell" to configure which Regions modules belong in.  How did the responsibility of the UI (e.g. Shell) end up in the Module?  That makes no sense.  I currently have to have a seperate config file which redundantly defines the Modules and tells the shell which Region to load them in.  This has also helped with Dynamically loading modules on demand because now the Shell can interrogate whether the module in the newly loaded Region has been loaded before or not and load it on demand.  It's nice.  However, not many developers ever see that they can do this because they're so caught up with the online examples that always show a Module doing something like "regionManager.RegisterViewWithRegion(...)".  It's really not intuitive and tightly couples Modules to one Shell.  Which the methodology I hinted to above, I could use the same Module in many different Shells.  Why can't the ModuleCatalog.xaml just support the markup to do something like that? Just my 2cents.

  • Anonymous
    January 31, 2010
    Is there any guidance on using Prism with MEF now?  I am starting a .NET 4.0 project.  I want to move to Prism 4 when available.

  • Anonymous
    February 01, 2010
    The comment has been removed

  • Anonymous
    February 01, 2010
    The comment has been removed

  • Anonymous
    February 15, 2010
    Thanks for this post David, it helps to understand the direction you guys are taking. I didn't have a chance to play with Prism in its current state, however in my company we built all our systems on top of CAB/SmartClient Software Factory.  On this end I wanted to ask you what is the direction on providing Software Factories for Prism 4.0, I can tell you that there is a great value on it, and it helped us a lot in particular aligning the development team on the same direction. You made this post in December, what is the current state of envisioning/development for Prism 4.0?  Any schedule you can share as far as when is going to be made available to public? Thanks again

  • Anonymous
    February 15, 2010
    Hi David, Can anybody suggest me a way for injecting the CAB Application Shell at run-time in Microsoft .NET Smart Client (CAB - Composite Application Block) GUI Applications using Unity Application Block ? Is it possible ? Any help will be appreciated. Thanks,

  • Anonymous
    February 17, 2010
    I would love to see the capability to load modules in different AppDomain for :

  • Limiting the impact of a module crashing
  • Be able to run a module with different credentials
  • Be able to have different configuration file per module What do you think about this ?
  • Anonymous
    February 19, 2010
    The comment has been removed

  • Anonymous
    February 23, 2010
    David, as you mentioned "in the case of Silverlight, modules can be downloaded with the core application, or can be downloaded in the background or on-demand", what about WPF?  one of the main issues I have today with CAB/Prism is that even though the conceptual idea is that modules are developed independently, you can't deploy them independently, you are force to deploy your entire system just make changes that affect one module, this seriously should be looked at in the next version, PLEASE!!! Thanks for listening

  • Anonymous
    February 24, 2010
    @Mr.Underhill - Deployment of a desktop WPF application is typically handled either by ClickOnce or by an MSI install. We provide guidance on using ClickOnce with Prism, focusing on deploying the app along with its modules via ClickOnce. But it sounds like your scenario is more along the lines of deploying individual modules. I'll add this scenario to the backlog for Prism 4.0... For WPF applications, Prism provides a Directory Catalog which loads modules that are found in an application sub-directory. So in principle we would 'just' need to deploy modules into that directory for them to get loaded in the application - we wouldn't need to redeploy the entire application, just the modules that have changed. It would be great if ClickOnce itself could handle this - so that, for example, we could either use ClickOnce to deploy individual modules into the app's module directory, or even better, so that ClickOnce could spot the delta between app v1 and v2 and just deploy the modules that have changed...

  • Anonymous
    February 24, 2010
    David, we looked at the guidance for Click Once and that's what we do, however the scenario is this.... let's say you have a Composite Application with 5 modules, each module let's say is used by different departments in the organization.... all those modules are deployed TOGETHER with ClickOnce.... let's say you need to do an enhancement to a module, in order to deploy THAT MODULE you have to deploy the entire application affecting as such users that are not even using the module that is changing... What I'm proposing is some guidance or underline mechanism that will allow the Shell to handle the deployment of the modules independently of each other so you can indeed take advantage of a modular system and add / update or remove modules truly independently from the deployment perspective. Let me know if this clarifies Thank you

  • Anonymous
    February 24, 2010
    ... just to clarify, what you propose using the Directory Catalog and Click Once been able to spot the delta between v1 and v2 seems to be a good solution.... it will be great if you guys can make it part of Prism 4.0, deployment at the end of the day is really important and to be a trully modular system, deployments needs to work as well Another issue we ran into is security... we use the IPricipal/IIdentity in our application to do application security... if you think about it, security is really something PER MODULE... each module has its own appliation security... .some users might use multiple modules and as such they will have to have multiple underline security tokens that deal with each of the modules.... we came up with a little technique to swap the principal/identity every time the module obtains the focus, but this I think should be part of the underline composite framework... let me know what you think....

  • Anonymous
    February 24, 2010
    @Mr.Underhill - Yes, that clarifies. I'll add this scenario to the backlog for Prism 4.0. If we do anything in this area it will be on top of ClickOnce, and hopefully it will be fairly straightforward. On the security front, we sometimes see apps that authenticate the user's identity once at the shell level, then the individual models authorize the user based on role. In other words, the user's identity is the same across all modules but authorization is per module based on role. RBAC, especially how it drives role-specific UI and behavior, is another thing on the backlog for Prism 4.0...

  • Anonymous
    March 03, 2010
    The comment has been removed