I am currently figuring out how to restructure the architecture of an existing not very modular ASP.NET MVC 3.0 application. I have a plugin like structure in mind to make the existing project extensible.
I have searched for different strategies to make modular web applications and found the following. I would like you to comment on these ideas.
- MVC Areas in separate Projects
For each plugin I want to create an individual ASP.NET MVC project that contains controllers, views and view models for the plugin. An "Employee" Module would contain an Area to list, create, update and delete employees. However this sounds good, AreaRegistration required to place all areas in the "bin" directory. I found a way to place my Area projects directly in the Areas folder and resolve the Area assemblies from the “/Areas/[AreaName]/bin” folder:
BuildManager.AddReferencedAssembly.Add(Assembly.LoadFrom(…));
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssemblies;
This is working quite well and allows me to deploy plugins in the Areas folder of the main project. I like that I am using the Areas feature which is provided out of the box by ASP.NET MVC.
- MVC Portable Areas (MVCContrib)
http://elegantcode.com/2012/04/06/mvc-portable-areas/
Portable Areas do not seem to be a good approach, since they require that views are compiled as embedded resources in the Area project file. This would prevent IIS caching. On the other hand I really cannot imagine how big the performance drawback really is.
- MVC based Modules using MEF
http://www.fidelitydesign.net/?p=104
In order to create loosely coupled services in other projects I heavily rely on MEF. Thus I thought it would be a great idea to use it to discover ASP.NET MVC Modules/Plugins. I would end up using a ControllerFactory that would instantiate Controllers exported by using the ‘Export’ attribute. This way I would have full control over the plugin instantiation and could use MEF to get services. However using MEF really requires much more work than using MVC Areas, which resolve controllers out of the box.
- Entity Framework across Plugin projects
One problem, I was unable to solve so far, is how to distribute the entities across the individual plugin projects. Currently we use a Database First approach, which consists of one *.edmx model file that contains all entities. Even with DbContext or Code First it is not possible to use multiple DbContext classes for one database. One idea would be to use MEF to load entities from different plugins into a central DbContext class. However I do not know whether this is a supported and/or recommended setup.