How does one integrate Managed Extensibility Framework (MEF) with ASP.NET MVC 4 and ASP.NET Web API in the same project?
Consider an example application, with an MVC controller HomeController
and a Web API controller ContactController
. Both have a property of type IContactRepository
, which they rely on MEF to resolve. The problem is how to plug MEF into MVC and Web API, so that instances are created via MEF.
HomeController:
/// <summary>
/// Home controller. Instruct MEF to create one instance of this class per importer,
/// since this is what MVC expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
[Import]
private IContactRepository _contactRepository = null;
public ActionResult Index()
{
return View(_contactRepository.GetAllContacts());
}
}
ContactController:
/// <summary>
/// Contact API controller. Instruct MEF to create one instance of this class per importer,
/// since this is what Web API expects.
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ContactController : ApiController
{
[Import]
private IContactRepository _contactRepo = null;
public Contact[] Get()
{
return _contactRepo.GetAllContacts();
}
}
IContactRepository and ContactRepository:
public interface IContactRepository
{
Contact[] GetAllContacts();
}
[Export(typeof(IContactRepository))]
public class ContactRepository : IContactRepository
{
public Contact[] GetAllContacts()
{
return new Contact[] {
new Contact { Id = 1, Name = "Glenn Beck"},
new Contact { Id = 2, Name = "Bill O'Riley"}
};
}
}
Contact:
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
}
The solution is to implement System.Web.Mvc.IDependencyResolver and System.Web.Http.Dependencies.IDependencyResolver and register your implementation with ASP.NET MVC and ASP.NET Web API respectively, in your
Application_Start
method.In this example we'll create a class
MefConfig
, which implements a methodRegisterMef
that gets called fromApplication_Start
in order to install our dependency resolver. The classMefDependencyResolver
implements bothSystem.Web.Mvc.IDependencyResolver
andSystem.Web.Http.Dependencies.IDependencyResolver
and, as such, handles dependency resolution duties for both MVC and Web API.Application_Start, Put This in Your Global.asax.cs:
MefDependencyResolver and MefConfig:
Mr Kenny Torduer's solution worked for me whilst the supposed correct answer did not (couldn't resolve the controller instance although all dependent parts are in the catelog, I was given a "type does not have a default constructor" error)!
Correction: both approaches work actually, I was being stupid by an elementary mistake in the convention parts registry. My sincere apology to the author of the right answer.
This is a simpler approach that I'm using in my MVC4 project.
In Application_Start run MefConfig.Initialise() and in FilterConfig.RegisterGlobalFilters(GlobalFilterCollection filters) put filters.Add(new Filters.MefFilterAttribute());
@aknuds1 answer is the best I've seen so far for integrating MEF into the DependencyResolver. I was able to extend it to use the convention-based composition in MEF2 fairly easily. The MefConfig class is all that needed to change and then not by much.
I followed @akanuds1's answer but I also had to change the ControllerFactory to this:
Glogal.asax.cs
You can take a look at this http://kennytordeur.blogspot.be/2012/08/mef-in-aspnet-mvc-4-and-webapi.html. It explains how to use MEF in an Asp.net MVC 4/Web Api project. There also exists a Nuget package based on this code. That way you can test it very easily and quickly.