ASP.NET MVC 4.0 and MEF controllers, how to bring these two together?

I am trying to create an ASP.NET MVC module using MEF. So far, I have no problem using MEF without MVC, when it comes to exporting controllers, I have some difficulties.

I used this approach as an example http://kennytordeur.blogspot.de/2012/08/mef-in-aspnet-mvc-4-and-webapi.html I made this more complicated by introducing an external dll containing the controller. But if I follow Kenny's idea, then I need to have a common interface (for example, IMyTest in his example), however, since I plan to have several controllers, this will mean that I will need too many interfaces. And in the end, it looks like I'm reusing internal controller methods, not whole controllers.

I found a question here How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API , which contains some code examples, where I see a similar picture - _contactRepository of the IContactRepository interface is imported and then reused inside the view.

That is why my question is: is it normal to export the entire controller without using interfaces? And how to do it?

I found that the connection between MEF and ASP.NET is rather confusing, at first it suggests that there are several examples on the Internet, but when I look deeper, most of them are outdated and not practical or too primitive to see how this can be applied to larger projects.

Thank!

+7
c # asp.net-mvc mef
Jul 10 '13 at 19:23
source share
1 answer

I used MefContrib along with MEF in MVC 4, and I use the following to connect everything. You need to call the Configure method from Application_Start in Global.asax so that everything is ready when MVC should process the request.

using System.ComponentModel.Composition.Hosting; using System.Linq; using System.Web; using System.Web.Mvc; using MefContrib.Hosting.Conventions; using MefContrib.Web.Mvc; [assembly: PreApplicationStartMethod( typeof(Core.Web.Initialization.DependencyInjection.RegisterDependencyResolver), "RegisterHttpModule" )] namespace Core.Web.Initialization.DependencyInjection { public class RegisterDependencyResolver { public static void RegisterHttpModule() { // Register the CompositionContainerLifetimeHttpModule HttpModule. // This makes sure everything is cleaned up correctly after each request. CompositionContainerLifetimeHttpModule.Register(); } public void Configure() { // Create MEF catalog based on the contents of ~/bin. // // Note that any class in the referenced assemblies implementing in "IController" // is automatically exported to MEF. There is no need for explicit [Export] attributes // on ASP.NET MVC controllers. When implementing multiple constructors ensure that // there is one constructor marked with the [ImportingConstructor] attribute. var catalog = new AggregateCatalog( new DirectoryCatalog( "bin" ), new ConventionCatalog( new MvcApplicationRegistry() ) ); // Tell MVC3 to use MEF as its dependency resolver. var dependencyResolver = new CompositionDependencyResolver( catalog ); DependencyResolver.SetResolver( dependencyResolver ); // Tell MVC3 to resolve dependencies in controllers ControllerBuilder.Current.SetControllerFactory( new DefaultControllerFactory( new CompositionControllerActivator( dependencyResolver ) ) ); // Tell MVC3 to resolve dependencies in filters FilterProviders.Providers.Remove( FilterProviders.Providers.Single( f => f is FilterAttributeFilterProvider ) ); FilterProviders.Providers.Add( new CompositionFilterAttributeFilterProvider( dependencyResolver ) ); // Tell MVC3 to resolve dependencies in model validators ModelValidatorProviders.Providers.Remove( ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single() ); ModelValidatorProviders.Providers.Add( new CompositionDataAnnotationsModelValidatorProvider( dependencyResolver ) ); // Tell MVC3 to resolve model binders through MEF. Model binders must be decorated with [ModelBinderExport]. ModelBinderProviders.BinderProviders.Add( new CompositionModelBinderProvider( dependencyResolver ) ); } } } 

In addition, you need to export your controllers to MVC. Here is an example of how I do this:

 [Export] [PartCreationPolicy( CreationPolicy.NonShared )] public partial class HomeController : ControllerCore { [ImportingConstructor] public HomeController( DataContext context, ILogFactory logFactory, ServiceFactory serviceFactory ) : base( context, logFactory, serviceFactory ) { } public virtual ActionResult Index() { return View(); } } 

Hope this helps!

+6
Jul 10 '13 at
source share



All Articles