2012-04-10 2 views
4

Wo ist der empfohlene Ort, um Property-Injection in Aktion Filterattribute in einem ASP.NET Web-API-Projekt durchzuführen? In MVC 3 Land konnten wir unsere eigene Implementierung für ControllerActionInvoker zum Zeitpunkt der Auflösung unserer Controller aus unserem IoC-Container setzen und die -Methode außer Kraft setzen, um aus dem Container gelöste Komponenten zu injizieren.Property Injection in Web API `` System.Web.Http.Filters.ActionFilterAttribute``

Gibt es einen ähnlichen Ort, um dies in einem ASP.NET-Web-API-Projekt zu tun? Ich habe eine Controller Fabrik, die Controller aus dem Behälter, mit dem CreateController Verfahren löst als so:

public IHttpController CreateController(HttpControllerContext controllerContext, string controllerName) 
{ 
    var controller = _kernel.Resolve<IHttpController>(controllerName); 

    controllerContext.Controller = controller; 
    controllerContext.ControllerDescriptor = new HttpControllerDescriptor(_configuration, controllerName, controller.GetType()); 

    return controllerContext.Controller; 
} 

ich einen Blick auf HttpControllerDescriptor gehabt habe, um zu sehen, ob es irgendwo ist die Injektion zu tun, aber ich kann nicht einen geeigneten Ort finden. Irgendwelche Hinweise in die richtige Richtung?

Antwort

3

Sie müssen IHttpControllerSelector implementieren und Ihre Wähler in der (Services Eigenschaft) des HttpConfiguration zu registrieren.

Oder alternativ, um Ihr eigenes Resolver/DI-Framework zu verwenden, müssen Sie den Resolver ersetzen. Ein Beispiel finden Sie in here.


Sie müssen Ihre eigenen IFilterProvider implementieren. Sehen Sie sich die Quelle für ActionDescriptorFilterProvider an. Hier können Sie Eigenschaften injizieren.

Hier ist ActionDescriptorFilterProvider Umsetzung:

public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) 
    { 
     if (configuration == null) 
     { 
      throw Error.ArgumentNull("configuration"); 
     } 

     if (actionDescriptor == null) 
     { 
      throw Error.ArgumentNull("actionDescriptor"); 
     } 

     IEnumerable<FilterInfo> controllerFilters = actionDescriptor.ControllerDescriptor.GetFilters().Select(instance => new FilterInfo(instance, FilterScope.Controller)); 
     IEnumerable<FilterInfo> actionFilters = actionDescriptor.GetFilters().Select(instance => new FilterInfo(instance, FilterScope.Action)); 

     return controllerFilters.Concat(actionFilters); 
    } 

Alles, was Sie tun müssen, ist instance Lambda-Parameter zu verwenden und Eigenschaften zu injizieren.

Registrierung Wie Sie herausgefunden haben, muss der Filteranbieter gegen die HttpConfiguration registriert werden. Oder, um Ihr eigenes Resolver/DI-Framework zu verwenden, müssen Sie den Resolver ersetzen. Ein Beispiel finden Sie in here.

+0

'IHttpControllerSelector' hilft hier nicht - das Problem ist nicht mit der Auflösung von Controllern richtig zu tun (das alles funktioniert gut), aber es geht darum, Dienste in Action-Filter zu injizieren. So könnte man es in MVC machen - http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/, aber Web API ist etwas anders. –

+0

@RussCam ja, missverstanden. Aktualisiert. – Aliostad

+0

Ich kam zum gleichen Ergebnis wie Sie :) Mein 'IFilterProvider', der mit dem Container registriert ist, scheint jedoch nie getroffen zu werden; Die Aktionsfilter werden ausgeführt, was darauf hindeutet, dass das Framework nicht versucht, den "IFilterProvider" aus dem Container aufzulösen. Es ist ein wenig frustrierend, da der Quellcode auf http://aspnetwebstack.codeplex.com/ nicht mehr aktuell ist mit den Assemblies von NuGet! –