2013-07-10 26 views
7

Sto provando a creare il modulo MVC ASP.NET utilizzando MEF. Anche se finora non ho avuto problemi con MEF senza MVC, quando si tratta di esportare i controller ho alcune difficoltà.ASP.NET MVC 4.0 Controller e MEF, come riunire questi due elementi?

Ho utilizzato questo approccio come esempio http://kennytordeur.blogspot.de/2012/08/mef-in-aspnet-mvc-4-and-webapi.html L'ho reso più complesso introducendo una DLL esterna, che conteneva un controller. Ma se seguo l'idea di Kenny, allora ho bisogno di avere un'interfaccia comune (come IMyTest nel suo esempio), tuttavia, poiché ho in programma di avere un numero di controller, significherebbe che avrò bisogno di troppe interfacce. E alla fine, sembra che io riutilizzi i metodi interni dei controller, invece di interi controllori.

Ho trovato una domanda qui How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API, che conteneva alcuni esempi di codice, dove vedo l'immagine simile - _contactRepository di un'interfaccia IContactRepository viene importata e quindi riutilizzata all'interno di una vista.

Ecco perché la mia domanda è, è normale esportare l'intero controller, senza utilizzare le interfacce? E come farlo?

Ho trovato la connessione tra MEF e ASP.NET piuttosto confusa, inizialmente mi sembra che ci siano una serie di esempi in Internet, ma quando guardo più in profondità, molti di loro sono obsoleti e non pratici o troppo primitivi per vedere come può essere applicato a progetti più grandi.

Grazie!

risposta

6

Ho usato MefContrib insieme a MEF in MVC 4 e sto usando quanto segue per collegare tutto. È necessario richiamare il metodo Configure da Application_Start in Global.asax in modo che tutto sia pronto quando MVC deve elaborare una richiesta.

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)); 
     } 
    } 
} 

Inoltre, è necessario esportare i controller su MVC. Ecco un esempio di come lo faccio:

[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(); 
    } 
} 

Spero che questo aiuti!

+0

Morten, grazie per la risposta! ho capito bene, che nella tua soluzione principale usi HomeController come qualsiasi altro controller? O hai bisogno di dichiararlo da qualche parte nell'applicazione principale? E cosa fa la classe ControllerCore? – Anelook

+0

ControllerCore è solo un controller di base: è possibile vedere che il costruttore richiama una classe base, in cui i parametri vengono utilizzati/memorizzati, ma è possibile utilizzarli direttamente nel HomeController senza avere una classe base. Il codice di configurazione carica MVC per utilizzare MEF quando crea controller, quindi non è necessario alcun codice aggiuntivo da nessuna parte (tranne la chiamata al metodo Configure in Application_Start, come menzionato nella risposta). –