As we are moving ahead we have already discussed the notion and usage of TypeCatalog, AssemblyCatalog or DirectoryCatalog, in this post I am going to discuss one more Complex Catalog Type that is already present in MEF Base class Library. The AggregateCatalog is a combination of 2 or more catalog and forms a unified Parts Library for your exports and imports. You can add Catalogs dynamically at runtime and the aggregate catalog parses the catalog and get all parts associated to itself.
This is generally a very common requirement when you want a combination of both Currently Executing Assembly and a specific Directory in which plugins co-exists. In such case your only option is to use AggregateCatalog in which we first add the AssemblyCatalog of current executing assembly and a DirectoryCatalog pointing to the directory where plugins are placed.
Lets use the demo that I have worked on in our last post, and modify it to include the currently executing assembly.
Lets add some Imports in the current assembly and load the same in AggregateCatalog. To do this we add a class like below :
public class PluginHost { [ImportMany] public IEnumerable> GetNames { get; set; } }
The class enumerates all the methods that return strings and produce an IEnumerable
of the same. We use ImportMany generally when plugins of same type can belong to a catalog. You can see I have used a delegate Func<string> as it is important to use delegate while you are going to import a method. If you are using a contract to do the same, you can make this an instance of an Interface used for contract.
As we are actually using the Executing assembly you can add a method of same type too. Lets add one like below :
[Export] public string GetPluginName() { return "Plugin from MEFPluginHost"; }
Now lets compose Parts for the assembly. To do this we add a DirectoryCatalog, an AssemblyCatalog and aggregate them into an AggregateCatalog, finally we use CompositionContainer to map parts.
DirectoryCatalog dcatalog = new DirectoryCatalog("plugins", "*.dll"); AssemblyCatalog acatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); AggregateCatalog catalog = new AggregateCatalog(dcatalog, acatalog); PluginHost host = new PluginHost(); CompositionContainer container = new CompositionContainer(catalog); container.ComposeParts(host); foreach (Func method in host.GetNames) Console.WriteLine(method()); Console.ReadKey(true);
The IEnumerable of the PluginHost will load methods from all the dlls present in the Directory as well as the method defined in the Executing assembly. The output of the application will be :
The AggregateCatalog
also allows you to hook up an EventHandler for ComposablePartCatalogChanged
and also lists all the existing catalog that is added to it.
Download sample code from here.
Read more about it from the links :
Managed Extensibility Framework – A Look
Steps to write a plugin based application with MEF
Thank you for reading.