Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API

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; } } 
like image 641
aknuds1 Avatar asked Nov 26 '12 14:11

aknuds1


People also ask

Is ASP Net Web API and ASP.NET MVC same?

Asp.Net MVC is used to create web applications that returns both views and data but Asp.Net Web API is used to create full blown HTTP services with easy and simple way that returns only data not view. 2.

How can I call MVC controller action from Web API?

You just need to make sure that you get your URLs right, so WebApi calls your MVC controller via it's properly qualified route. To test this, write a simple MVC action which returns some Json data and call it in the browser. If you manage to craft the URL correctly you will see the data displayed in the browser.

Can I use MVC controller as Web API?

Before I illustrate how an ASP.NET MVC controller can be used as an API or a service, let's recap a few things: Web API controller implements actions that handle GET, POST, PUT and DELETE verbs. Web API framework automatically maps the incoming request to an action based on the incoming requests' HTTP verb.


1 Answers

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 method RegisterMef that gets called from Application_Start in order to install our dependency resolver. The class MefDependencyResolver implements both System.Web.Mvc.IDependencyResolver and System.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:

public class WebApiApplication : System.Web.HttpApplication {     protected void Application_Start()     {         [...]         MefConfig.RegisterMef();     } } 

MefDependencyResolver and MefConfig:

/// <summary> /// Resolve dependencies for MVC / Web API using MEF. /// </summary> public class MefDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver, System.Web.Mvc.IDependencyResolver {     private readonly CompositionContainer _container;      public MefDependencyResolver(CompositionContainer container)     {         _container = container;     }      public IDependencyScope BeginScope()     {         return this;     }      /// <summary>     /// Called to request a service implementation.     ///      /// Here we call upon MEF to instantiate implementations of dependencies.     /// </summary>     /// <param name="serviceType">Type of service requested.</param>     /// <returns>Service implementation or null.</returns>     public object GetService(Type serviceType)     {         if (serviceType == null)             throw new ArgumentNullException("serviceType");          var name = AttributedModelServices.GetContractName(serviceType);         var export = _container.GetExportedValueOrDefault<object>(name);         return export;     }      /// <summary>     /// Called to request service implementations.     ///      /// Here we call upon MEF to instantiate implementations of dependencies.     /// </summary>     /// <param name="serviceType">Type of service requested.</param>     /// <returns>Service implementations.</returns>     public IEnumerable<object> GetServices(Type serviceType)     {         if (serviceType == null)             throw new ArgumentNullException("serviceType");          var exports = _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));         return exports;     }      public void Dispose()     {     } }  public static class MefConfig {     public static void RegisterMef()     {         var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());         var container = new CompositionContainer(asmCatalog);         var resolver = new MefDependencyResolver(container);         // Install MEF dependency resolver for MVC         DependencyResolver.SetResolver(resolver);         // Install MEF dependency resolver for Web API         System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = resolver;     } } 
like image 87
aknuds1 Avatar answered Sep 21 '22 00:09

aknuds1