AutoFac e ASP.NET Web API Apicontroller
-
13-11-2019 - |
Domanda
Ho usato AutoFac con MVC 3 per un po 'e lo adoro. Di recente ho aggiornato un progetto a MVC 4 e tutto sembra funzionare, tranne per gli APIController Web API. Sto ricevendo la seguente eccezione.
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 tramite AutoFac. Mi manca qualcosa o c'è qualcosa nelle opere. Lo so, MVC4 è appena uscito ed è una beta, quindi non mi aspetto molto, ma ho pensato che avrei potuto perdere qualcosa.
Soluzione
Ho rilasciato pacchetti di integrazione AutoFAC su NuGet per le versioni beta di MVC 4 e API Web. Le integrazioni creeranno un ambito a vita AutoFac per richiesta del controller (controller MVC o controller API a seconda dell'integrazione). Ciò significa che il controller e le sue dipendenze verranno automaticamente disposte alla fine di ogni chiamata. Entrambi i pacchetti possono essere installati fianco a fianco 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
API Web
https://nuget.org/packages/autofac.webapi/
http://alexmg.com/post/2012/03/09/autofac-aspnet-web-api-(beta)-integration.aspx
I collegamenti sono ora fissati.
Altri suggerimenti
L'ho appena configurato su una delle mie app. Esistono diversi modi per farlo, ma mi piace questo approccio:
AutoFac e ASP.NET Web API System.Web.http.services.idependencyResolver Integrazione
Per prima cosa ho creato una classe che implementa System.Web.Http.Services.IDependencyResolver
interfaccia.
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 ho un'altra classe che contiene le mie 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();
}
}
Quindi, inizializzalo a Application_Start
:
protected void Application_Start() {
//...
AutofacWebAPI.Initialize();
//...
}
Spero che questo aiuti.