Best Practices for Composed ASP.NET MVC Web Applications (MEF, Areas, DI)
Asked Answered
D

1

11

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.

Directoire answered 26/8, 2012 at 9:6 Comment(0)
M
4

Another option is to use my Griffin.MvcContrib. It takes care of all plumbing for you and allows you to write views and use areas with little code changes.

Use it together with a IoC container to get a powerful plugin system.

Here is an article that demonstrates how: http://www.codeproject.com/Articles/386674/ASP-NET-MVC-3-plug-in-architecture-using-Griffin-M

Morris answered 27/8, 2012 at 5:55 Comment(5)
Thank you for pointing me to your Griffin.MvcContrib project. Looks great! One last question: How do you share entities using Entity Framework between plugins? Or must all entities reside within one data layer project?Directoire
I do not share EF entities (I usually abstract away the data source using a mapper between the db entities and the business objects), but I would put common entities in a separate projectMorris
But doesn't this require duplicate code, since the EF entity classes and my domain classes are basically the same? Furthermore I cannot query against domain classes, because they do not implement IQueryable.Directoire
@jgauffin, all the approaches I have seen on the internet require the main website to be restarted in case of adding a new plugin or area or update the existing one. I want to develop a website which should be able to add new module without restarting the parent website. Is it possible?Chiton
ASP.NET applications are reloaded every time a DLL is added or changed. Hence you cannot prevent new plugins from getting added.Morris

© 2022 - 2024 — McMap. All rights reserved.