Suggestion: Migrate to MEF

Jun 29, 2010 at 9:10 PM

Looking through the code, I see you're using BuildManager for discovering types in the system. I hadn't actually known about BuildManager before, so I looked into it and it's quite useful. That said, I think it would be beneficial to use MEF for type loading in addition to just the BuildManager. This way you can load all of the IModule instances that might be in other assemblies in the bin folder that aren't otherwise referenced by the application. All it would require on the developer's part is to mark an IModule instance with an attribute of [Export(typeof(IModule))]. Thoughts?

Jul 6, 2010 at 7:32 PM

As a quick workaround, I came up with the following code in my Application class. It adds all assemblies to the BuildManager that contain an exported IModule. This takes care of modules and bootstrapper tasks.

protected void Application_PreStartInit()
{
     // Add assemblies containing IModules to the BuildManager
     var catalog = new DirectoryCatalog("bin");
     var compositionContainer = new CompositionContainer(catalog);
     var modules = compositionContainer.GetExportedValues<IModule>();

     var assemblies = new HashSet<Assembly>();
     modules.Each(m => assemblies.Add(m.GetType().Assembly));
          
     assemblies.Each(BuildManager.AddReferencedAssembly);
}

 

Coordinator
Jul 7, 2010 at 8:39 PM
I am still not convinced with the usage of MEF in WebApp. One of the member of this project was assigned to start experimenting the MEF integration, but I have not heard from him anything recently.
Jul 8, 2010 at 1:46 PM
Edited Jul 8, 2010 at 1:47 PM
kazimanzurrashid wrote:
I am still not convinced with the usage of MEF in WebApp. One of the member of this project was assigned to start experimenting the MEF integration, but I have not heard from him anything recently.

I looked at trying to add MEF to your source and ended up giving up for the above solution. I am by no means a MEF expert, but here are the issues I ran into:

  • MEF will give you instances, where MVCEX generally needs types (BootstrapperTask, for example) to plug into the IOC container.
  • MEF doesn't readily expose anything at the assembly level, which is the reasoning for the hack I did above with module.GetType().Assembly.

It was trivial to add support for modules using MEF because I could just load all instances of them immediately. I wasn't able to succeed using the Bootstrapper tasks though, since I just needed their types exposed. Also, I did not want to have to put an Export attribute on every BootstrapperTask class I had (which I did for the IModules).

I think if you're going to use MEF, you'd likely need to re-architect the entire module/bootstrapper system and somehow tie it in with the current IOC container to provider services to the objects it instantiates. The BuildManager is great until you need multiple assemblies like I did.

If I have some time I'll dive a little deeper into MEF and let you know if I find a way it might be integrated better.