Friday, February 20, 2009

Using MEF to extend a HttpModule

I watched Glen Blocks PDC demo for the Managed Extensibility Framework (MEF) last year and thought it would be a great tool to use if I ever created a client application that had to provide a plug-in mechanism. As I write web based business applications I didn’t think this would be any time soon. Added to this I am using the Castle Windsor Inversion of Control container so I didn’t think I had a need for another container.

Background

I’m currently working on a project that has a central application for user authentication. Each client application calls a webservice to check the user’s credentials and, if all is well, a principal is added to the HttpContext. This process is all wrapped up in a HttpModule. My task is to create a variety of cookies to authenticate users with 3rd party or legacy systems once they are authenticated. The best place to do this is within the HttpModule but this is used by a variety of applications. To solve this I used MEF to create a pluggable PostAuthorization mechanism.

MEF and the HttpModule

My goal is to be able to write a component that can set a client cookie. As it is dealing with user information is will also have to access the user stored in the HttpContext.  I created this interface to start with


MEF creates dependencies at runtime whereas an IoC usually has a configuration process which defines the concrete instance to be created for the abstract services. In my httpModule I created a list of CookieSetters that MEF could populate:


By attributing the collection with [Import] I'm telling MEF to wire up all assemblies it discovers that implement ISetCookies. Now this is in place it is time to start up MEF, and this being a HttpModule the place to do the work is in the Init method


The creation of the container, which I lifted from the CodePlex site, creates:
  • A catalog of all the assemblies in the bin folder, anything attributed with an Export will be added to the catalog.
  • A composition batch that will consume the exported assemblies, anything attributed with Import will be added to the batch.
  • A container to hold it all and orchestrate the magic.

Now I can create my PostAuthroization event to kick off any CookieSetters MEF has found:


Here I first check that the list has been created and then call the SetCookie method on each one. Below is a trivial example of a CookieSetter


Summary

When working with different teams being able to provide simple extension points is great and I can see MEF being the tool for the job. It will also be a good tool to have alongside an IoC as the two are complimentry.

As for the code above it solves a problem for me but still needs some work as the container will be built everytime the module is loaded causing a nasty performance hit. Putting in the HttApplicationState as described by Michael Puleio will be the best solution.

No comments: