Thursday 25 March 2010

Problems with MEF

I have been implementing MEF in a large Windows project. Within the project we have lazy loading objects like Tasks and various models. It is necessary to create separate classes for these collections of objects. These classes have imports that need to be resolved. The problem is that the Imports must be satisfied by a creating the dependency containers within the class. This takes a long time because MEF uses reflection to search for exports within the assemblies, in our case we have a very large code base and this takes a long time. It also means a lot of code duplication for classes that use cross cutting concerns like loggers because before using the class the Imports must be satisfied. The other problem we had was that if we needed to import a single export and that there are more than 1 available (eg Logger and NullLogger) then MEF does not resolve this and does not give any warning about what is going on. We also found that making unit tests was difficult because we had no control over the composition.

So we are looking again at Spring.net. The main reason is that we want to compose our container once at the start of the application. Composition is a very time consuming operation and we don’t want to have decomposition. Since Spring.net uses a configuration file we have more control over the composition which is handy when it comes to unit testing. If we use an interface to the Spring compose method we can use mocks in our unit tests. Our application does not require the ability to dynamically recompose when a new dll is dropped into a directory because our application runs in a batch mode which means it will respond to changes in the configuration simply the next time the batch is run.

Over the last month I do realize that there are a number of scenarios when MEF would be the better choice, in particular in Silverlight applications. I am lucky that my application has been architected in such a way that the choice of dependency injection technology is orthogonal to the overall design of the application because we used SOLID OO principles and programmed cross cutting concerns with interfaces.