Catalogs

One of value propositions of MEF's attributed programming model is the ability to dynamically discover parts via catalogs. Catalogs allow applications to easily consume exports that have self-registered themselves via the Export attribute. Below is a list the catalogs MEF provides out of the box.

Assembly Catalog

To discover all the exports in a given assembly one would use the [System.ComponentModel.Composition.Hosting.AssemblyCatalog].

var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());

Directory Catalog

To discover all the exports in all the assemblies in a directory one would use the [System.ComponentModel.Composition.Hosting.DirectoryCatalog].

var catalog = new DirectoryCatalog("Extensions");
If a relative directory is used it is relative to the base directory of the current AppDomain.

The DirectoryCatalog will do a one-time scan of the directory and will not automatically refresh when there are changes in the directory. However, you can implement your own scanning mechanism, and call Refresh() on the catalog to have it rescan. Once it rescans, recomposition will occur.

var catalog = new DirectoryCatalog("Extensions");
//some scanning logic
catalog.Refresh();

Aggregate Catalog

When AssemblyCatalog and DirectoryCatalog are not enough individually and a combination of catalogs is needed then an application can use an [System.ComponentModel.Composition.Hosting.AggregateCatalog]. An AggregateCatalog combines multiple catalogs into a single catalog. A common pattern is to add the current executing assembly, as well as a directory catalog of third-party extensions. You can pass in a collection of catalogs to the AggregateCatalog constructor or you can add directly to the Catalogs collection i.e. catalog.Catalogs.Add(...)

var catalog = new AggregateCatalog(
  new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()), 
  new DirectoryCatalog("Extensions"));

Type Catalog

To discover all the exports in a specific set of types one would use a [System.ComponentModel.Composition.Hosting.TypeCatalog].

var catalog = new TypeCatalog(typeof(type1), typeof(type2), ...);

Using catalog with a Container

To use a catalog with the container, simpy pass the catalog to the container's constructor.

var container = new CompositionContainer(catalog);
Last edited Oct 27 2009 at 10:41 PM by weshaggard, version 13
Comments
mabster Feb 10 2009 at 11:31 AM 
This code:

var catalog = new AggregateCatalog(new [] {
new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
new DirectoryCatalog("Extensions") });

Gives me a compile-time "No best type found for implicit array" error. It certainly seems like it should work, since both types derive from ComposablePartCatalog. This is with Visual C# Express 2008 SP1.

fa3den Mar 27 2009 at 9:42 PM 
The compiler can't infer the type from the inputs. Instead of "new[] {" put in "new ComposablePartCatalog[] {" and it will work.

wallyn May 20 2009 at 3:46 PM 
A nice option would be if you added the ability to the DirectoryCatalog to search sub-directories.

nadendla May 26 2009 at 5:20 PM 
Is there a way to perform license check on imports prior to loading the assemblies?

gentledepp Jun 29 2009 at 1:16 PM 
If i wanted to use this for plugis/addins, I'd like to watch the plugin-directory for any changes and if so, automatically start the new plugins. In that case, I'd need to either wait for all these changed plugins to shut down or kill em all and then load the new/modified versions.
Would that be doable with MEF or is it the wrong framework for that?

nblumhardt Jul 7 2009 at 4:45 PM 
Thanks for the corrections, updated now. The feature suggestions might be better posted to the discussions list.

BillL Jul 7 2009 at 9:05 PM 
The Directory Catalog info needs to be corrected, as the file system watcher no longer exists in MEF.

gblock Jul 8 2009 at 6:38 AM 
BillL I updated thanks.

lancecontreras Jul 24 2009 at 7:19 AM 
Does it mean that MEF won't be supporting the watchDirectory parameter of the DirectoryCatalog? Do we have any alternative for this feature? Because right now I need something that will load and display plugin's UI to the host application.

nblumhardt Jul 31 2009 at 12:02 AM 
@lancecontreras, correct. You can use a DirectoryWatcher from the .NET Framework + the AggregateCatalog to achieve this if you like. The DirectoryCatalog that shipped with earlier MEF releases might be a good place to look for example code (the older downloads are still available.)

nblumhardt Jul 31 2009 at 12:05 AM 
Correction - the Refresh() method (rather than AggregateCatalog) is the way to update MEF when the directory watcher fires.

Updating...
© 2006-2010 Microsoft | About CodePlex | Privacy Statement | Terms of Use | Code of Conduct | Advertise With Us | Version 2010.1.12.16187