2012-07-14 13 views
51

È possibile configurare Autofac per funzionare con ASP .NET MVC e ASP .NET Web Api. Sono consapevole che i resolver di dipendenza sono diversi. Ma quando si utilizzano gli approcci documentati posso solo impostare un risolutore globale.È possibile configurare Autofac per lavorare con ASP.NET MVC e ASP.NET Web Api

// Set the dependency resolver implementation. 
GlobalConfiguration.Configuration.DependencyResolver = resolver; 

Questa è una cattiva idea? Devo separare la mia soluzione in due progetti e gestire l'iniezione delle dipendenze per ciascuno di essi?

+0

Ho un'implementazione minima qui: http://byterot.blogspot.co.uk/2012/04/aspnet-web-api-series-part-4-dependency.html – Aliostad

risposta

82

è certamente possibile configurare Autofac per funzionare con MVC e Web API. Questo dovrebbe essere uno scenario molto comune. Esistono due implementazioni separate del resolver delle dipendenze perché MVC e Web API possono essere utilizzate indipendentemente l'una dall'altra. Lo stesso vale per le integrazioni di Autofac.

Quando si utilizzano sia MVC sia l'API Web nella stessa applicazione, ciascuno richiede il proprio resolver di dipendenza, sebbene possano essere forniti con la stessa istanza del contenitore.

var builder = new ContainerBuilder(); 

// Add your registrations 

var container = builder.Build(); 

// Set the dependency resolver for Web API. 
var webApiResolver = new AutofacWebApiDependencyResolver(container); 
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver; 

// Set the dependency resolver for MVC. 
var mvcResolver = new AutofacDependencyResolver(container); 
DependencyResolver.SetResolver(mvcResolver); 

E 'anche possibile condividere le registrazioni tra i due perché i InstancePerApiRequest e InstancePerHttpRequest ambiti di tutta la vita ora condividono lo stesso tag.

Si noti che il meccanismo per l'impostazione del resolver di risoluzione per Web API e MVC è diverso. L'API Web utilizza GlobalConfiguration.Configuration.DependencyResolver e MVC utilizza DependencyResolver.SetResolver.

+0

Ottima risposta. L'unica cosa è "perché MVC e Web API possono essere usati indipendentemente l'uno dall'altro". Suppongo che autofac abbia due plugin per mvc e webapi separatamente perché i due hanno runtime differente. – anIBMer

+0

WebApi non usa 'GlobalConfiguration' per dire, piuttosto usa' HttpConfiguration' che nel caso di progetti basati su owin può essere semplicemente istanziato e usato in tal modo: 'config.DependencyResolver = new AutofacWebApiDependencyResolver (...)'. –

4

Separarli definitivamente. Autofac ha entrambe le integrazioni ASP.NET MVC e ASP.NET Web API. Questo non è sempre il caso, ma se hai bisogno degli stessi servizi in entrambe le applicazioni, molto probabilmente c'è qualcosa di sbagliato nell'architettura dell'applicazione.

Ecco come si potrebbe fare questo con ASP.NET Web API:

internal class AutofacWebAPI { 

    public static void Initialize(HttpConfiguration config) { 

     config.DependencyResolver = new AutofacWebApiDependencyResolver(
      RegisterServices(new ContainerBuilder()) 
     ); 
    } 

    private static IContainer RegisterServices(ContainerBuilder builder) { 

     builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).PropertiesAutowired(); 

     //deal with your dependencies here 
     builder.RegisterType<CarsService>().As<ICarsService>(); 
     builder.RegisterType<CarsCountService>().As<ICarsCountService>(); 

     return builder.Build(); 
    } 
} 

Poi, registrare questo all'interno del Global.asax.cs come di seguito:

AutofacWebAPI.Initialize(GlobalConfiguration.Configuration); 
+1

È vero. È meglio separare il front-end e la configurazione dei servizi nello stesso progetto. –

11

ho pensato di aggiungere un po 'di aiuto coloro che lottano con questo mvc5 e web API 2.

Prima aggiungere pacchetti Nuget

  • Autofac
  • Autofac asp.net mvc 5 integrazione
  • Autofac asp.net web api 2.x integrazione

in globale aggiuntivo in Application_Start (o come app_start classe) aggiungi chiamata alla classe di sotto

AutofacConfig.RegisterAutoFac(); 

Ora aggiungere questa classe sotto App_start

using System.Reflection; 
using System.Web.Http; 
using System.Web.Http.Controllers; 
using System.Web.Mvc; 
using Autofac; 
using Autofac.Integration.Mvc; 
using Autofac.Integration.WebApi; 

namespace Example1.Web 
{ 
    public class AutofacConfig 
    { 
     public static IContainer RegisterAutoFac() 
     { 
      var builder = new ContainerBuilder(); 

      AddMvcRegistrations(builder); 
      AddRegisterations(builder); 

      var container = builder.Build(); 

      DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
      GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

      return container; 
     } 

     private static void AddMvcRegistrations(ContainerBuilder builder) 
     { 
      //mvc 
      builder.RegisterControllers(Assembly.GetExecutingAssembly()); 
      builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly()); 
      builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); 
      builder.RegisterModelBinderProvider(); 

      //web api 
      builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).PropertiesAutowired(); 
      builder.RegisterModule<AutofacWebTypesModule>(); 
     } 

     private static void AddRegisterations(ContainerBuilder builder) 
     { 
      //builder.RegisterModule(new MyCustomerWebAutoFacModule()); 
     } 
    } 
} 

Da oggi per ogni nuovo assembly che aggiungi al progetto aggiungi un nuovo modulo e poi registra il modulo nella funzione AddRegisterations (esempio dato)

Nota:

Ho restituito il contenitore, questo non è necessario.

Questo esegue la scansione dell'assieme corrente per i moduli, quindi non aggiungere moduli locali in AddRegisterations altrimenti si registrerà tutto due volte.

+1

grazie. Finalmente qualcuno che lo mette qui fuori in modo semplice e facile da capire senza imporre pareri, ecc. – punkologist

Problemi correlati