Ich benutze überall in meiner ASP.NET CORE
-Anwendung die Konstruktorbasierte Abhängigkeitsinjektion und muss auch Abhängigkeiten in meinen Aktionsfiltern auflösen:
public class MyAttribute : ActionFilterAttribute
{
public int Limit { get; set; } // some custom parameters passed from Action
private ICustomService CustomService { get; } // this must be resolved
public MyAttribute()
{
}
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// my code
...
await next();
}
}
Dann im Controller:
[MyAttribute(Limit = 10)]
public IActionResult()
{
...
Wenn ich ICustomService in den Konstruktor stecke, kann ich mein Projekt nicht kompilieren. Wie kann ich also Schnittstelleninstanzen im Aktionsfilter abrufen?
Wenn Sie das Service Locator-Muster vermeiden möchten, können Sie DI durch Konstruktorinjektion mit einem TypeFilter
verwenden.
In Ihrem Controller verwenden
[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
public IActionResult() NiceAction
{
...
}
Und Ihr ActionFilterAttribute
muss nicht mehr auf eine Dienstanbieterinstanz zugreifen.
public class MyActionFilterAttribute : ActionFilterAttribute
{
public int Limit { get; set; } // some custom parameters passed from Action
private ICustomService CustomService { get; } // this must be resolved
public MyActionFilterAttribute(ICustomService service, int limit)
{
CustomService = service;
Limit = limit;
}
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await next();
}
}
Für mich scheint die Annotation [TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
umständlich zu sein. Um eine lesbarere Annotation wie [MyActionFilter(Limit = 10)]
zu erhalten, muss Ihr Filter von TypeFilterAttribute
erben. Meine Antwort von Wie füge ich einem Aktionsfilter in asp.net einen Parameter hinzu? zeigt ein Beispiel für diesen Ansatz.
Sie können Service Locator
verwenden:
public void OnActionExecuting(ActionExecutingContext actionContext)
{
var service = actionContext.HttpContext.RequestServices.GetService<IService>();
}
Beachten Sie, dass die generische Methode GetService<>
eine Erweiterungsmethode ist und sich im Namensraum Microsoft.Extensions.DependencyInjection
befindet.
Wenn Sie die Konstruktorinjektion verwenden möchten, verwenden Sie TypeFilter
. Siehe Wie füge ich einen Parameter zu einem Aktionsfilter in asp.net hinzu?
Sie können ServiceFilters verwenden, um die benötigten ActionFilters im Controller zu instanziieren.
Im Controller:
[ServiceFilter(typeof(TrackingAttribute), Order = 2)]
Sie müssen TrackingAttribute im Abhängigkeitscontainer registrieren, damit der ServiceFilter es auflösen kann.
Lesen Sie mehr darüber unter https://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/