One of my recent projects was on Social Networking where we worked with various social networking sites like WL, Facebook, Delicious, Twitter ,Picassa, Flickr etc to bring them to a common platform for a user.
It was a pretty interesting application and i’ll try to demonstrate multiple WPF patterns we implemented in it.
One was the use of Plugin model using the “Managed Extensibility Framework”. The user could upload his photographs to multiple providers at the same time. The challenge given here was “we should be able to add another provider to the system at any time after the application is already deployed”. So at the time of development we develop for Flickr and Picassa but now YouTube is also allowing Photo upload so now we want to support You Tube but without opening up the code!!
We used the Managed Extensibility Framework for this.I’ll explain the core concepts of MEF(mostly picked up from the MEF guidelines document) and show you how we implemented this seemingly tough requirement easily.
What is MEF?
The Managed Extensibility Framework (or MEF for short) simplifies the creation of extensible applications. MEF offers discovery and composition capabilities that you can leverage to load application extensions.
- MEF provides a standard way for the host application to expose itself and consume external extensions. Extensions, by their nature, can be reused amongst different applications. However, an extension could still be implemented in a way that is application-specific. Extensions themselves can depend on one another and MEF will make sure they are wired together in the correct order (another thing you won’t have to worry about).
- MEF offers a set of discovery approaches for your application to locate and load available extensions.
- MEF allows tagging extensions with additonal metadata which facilitates rich querying and filtering
MEF is all about composable parts, which come in two flavours; imports and exports. An export is something you want to share and an import is the point at which you want to inject an export.
So in our case the “Photo Providers” are our “Exports” and the core Platform Consolidation application had an “Import” point for them.
MEF needs to a way of knowing about what exports it has at its disposal and what imports require “composing” (or matching up to available exports). In MEF this is the CompositionContainer which contains a Catalog of exports
So basically your “Catalog” has all the “Exports” Now how you make the Catalog is very important to how your exports will be identified.
There are multiple Catalog Options available for WPF
Assembly Catalog
To discover all the exports in a given assembly
Directory Catalog
To discover all the exports in all the assemblies in a directory .The DirectoryCatalog will do a one-time scan of the directory and will not automatically refresh when there are changes in the directory.
Aggregate Catalog
When AssemblyCatalog and DirectoryCatalog are not enough individually and a combination of catalogs is needed then an application can use an **Aggregate Catalog.**An AggregateCatalog combines multiple catalogs into a single catalog.
Type Catalog
To discover all the exports in a specific set of types one would use the Type Catalog.
Since we wanted a model where we just drop a new dll into the project and the new provider is up and running we went ahead with Directory Catalog.
Here are the 3 steps we did
- The Imports and Exports need to agree to an Interface. So we made an IPhotoProviderInterface and the Exports i.e the PhotoProviders adhered to it.
- Marked the Providers with the “Export” attribute for the IPhotoProviderInterface
[Export(typeof(IPhotoProviderInterface))]
public class PicassaProvider :IPhotoProviderInterface
{
...
}
On Application(Our CompositionContainer) Startup we wrote code to read a specific directory to look for exports .
- Create a list of IPhotoProviders which will hold instances of the providers going to be loaded and mark it with the Import Attribute
[Import]
public IEnumerable<IPhotoProviderInterface> PhotoProviders { get; set; }
- Create a DirectoryCatalog to read the new providers…
private void LoadProviders()
{
try
{
var catalog = new DirectoryPartCatalog(@".\Providers\");
var container = new CompositionContainer(catalog);
container.AddPart(this);
container.Compose();
foreach (IPhotoProviderInterface sender in PhotoProviders)
{
......
}
}
}
From here onwards the Providers were present in the PhotoProviders list….
It was a pretty neat implementation and we got a 100% for extensibility here…MEF looks daunting with all these new keywords but its pretty simple to implement!!
If you are looking to make a scalable and extensible application…we have the expertise and the experience to help you get there….drop us a note at cennesttech@hotmail.com..
Until Next time!
Cennest