2012-02-26 2 views
9

Ho usato autofac con MVC 3 per un po 'e lo adoro. Recentemente ho aggiornato un progetto in MVC 4 e tutto sembra funzionare tranne che per Web Api ApiControllers. Sto ottenendo la seguente eccezione.Autofac e API Web ASP.NET ApiController

An error occurred when trying to create a controller of type 'MyNamespace.Foo.CustomApiController'. Make sure that the controller has a parameterless public constructor. 

Questo mi sembra un problema con DI via autofac. Mi manca qualcosa o c'è qualcosa nelle opere. Lo so, MVC4 è appena uscito ed è una beta quindi non mi aspetto molto ma ho capito che potevo mancare qualcosa.

risposta

10

Ho rilasciato pacchetti di integrazione di Autofac su NuGet per le versioni Beta di MVC 4 e Web API. Le integrazioni creeranno un ambito di vita Autofac per richiesta di controller (controller MVC o controller API a seconda dell'integrazione). Ciò significa che il controller e le sue dipendenze verranno automaticamente eliminati al termine di ogni chiamata. Entrambi i pacchetti possono essere installati side-by-side nello stesso progetto.

MVC 4

https://nuget.org/packages/Autofac.Mvc4

http://alexmg.com/post/2012/03/09/Autofac-ASPNET-MVC-4-(Beta)-Integration.aspx

Web API

https://nuget.org/packages/Autofac.WebApi/

http://alexmg.com/post/2012/03/09/Autofac-ASPNET-Web-API-(Beta)-Integration.aspx

I collegamenti sono stati corretti.

+1

Sfortunatamente, a partire dalla digitazione di questo commento, sembra che utilizzare Autofac per MVC 4 RC e Web API RC allo stesso tempo non funzioni. Ricevo avvisi del compilatore sui tipi non trovati negli assembly della framework API Web. Ho dovuto usare la risposta fornita da @tugberk e ri-implementare il resolver di risoluzione per aggirarlo. – NathanAldenSr

4

Ho appena configurato questo in una delle mie app. Ci sono diversi modi per farlo, ma mi piace questo approccio:

Autofac and ASP.NET Web API System.Web.Http.Services.IDependencyResolver Integration

Per prima cosa ho creato una classe che implementa l'interfaccia System.Web.Http.Services.IDependencyResolver.

internal class AutofacWebAPIDependencyResolver : System.Web.Http.Services.IDependencyResolver { 

    private readonly IContainer _container; 

    public AutofacWebAPIDependencyResolver(IContainer container) { 

     _container = container; 
    } 

    public object GetService(Type serviceType) { 

     return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : null; 
    } 

    public IEnumerable<object> GetServices(Type serviceType) { 

     Type enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType); 
     object instance = _container.Resolve(enumerableServiceType); 
     return ((IEnumerable)instance).Cast<object>(); 
    } 
} 

e non ho un'altra classe che detiene i miei registrazioni:

internal class AutofacWebAPI { 

    public static void Initialize() { 
     var builder = new ContainerBuilder(); 
     GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
      new AutofacWebAPIDependencyResolver(RegisterServices(builder)) 
     ); 
    } 

    private static IContainer RegisterServices(ContainerBuilder builder) { 

     builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly).PropertiesAutowired(); 

     builder.RegisterType<WordRepository>().As<IWordRepository>(); 
     builder.RegisterType<MeaningRepository>().As<IMeaningRepository>(); 

     return 
      builder.Build(); 
    } 
} 

Poi, inizializzarlo a Application_Start:

protected void Application_Start() { 

    //... 

    AutofacWebAPI.Initialize(); 

    //... 
} 

Spero che questo aiuta.