J'utilise l'injection de dépendance basée sur le constructeur partout dans mon application ASP.NET CORE
et j'ai également besoin de résoudre les dépendances dans mes filtres d'action:
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();
}
}
Puis dans le contrôleur:
[MyAttribute(Limit = 10)]
public IActionResult()
{
...
Si je mets ICustomService au constructeur, je suis incapable de compiler mon projet. Alors, comment puis-je utiliser des filtres pour obtenir des instances d'interface?
Si vous souhaitez éviter le motif Service Locator, vous pouvez utiliser DI par injection de constructeur avec un TypeFilter
.
Dans votre contrôleur utiliser
[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
public IActionResult() NiceAction
{
...
}
Et votre ActionFilterAttribute
n'a plus besoin d'accéder à une instance de fournisseur de service.
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();
}
}
Pour moi, l'annotation [TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})]
semble gênante. Pour obtenir une annotation plus lisible telle que [MyActionFilter(Limit = 10)]
, votre filtre doit hériter de TypeFilterAttribute
. Ma réponse de Comment puis-je ajouter un paramètre à un filtre d'action dans asp.net? montre un exemple pour cette approche.
Vous pouvez utiliser Service Locator
:
public void OnActionExecuting(ActionExecutingContext actionContext)
{
var service = actionContext.HttpContext.RequestServices.GetService<IService>();
}
Notez que la méthode générique GetService<>
est une méthode d'extension et réside dans l'espace de noms Microsoft.Extensions.DependencyInjection
.
Si vous souhaitez utiliser l'injection de constructeur, utilisez TypeFilter
. Voir Comment ajouter un paramètre à un filtre d'action dans asp.net?
Vous pouvez utiliser ServiceFilters pour instancier les ActionFilters dont vous avez besoin dans le contrôleur.
Dans le contrôleur:
[ServiceFilter(typeof(TrackingAttribute), Order = 2)]
Vous devez enregistrer TrackingAttribute dans le conteneur de dépendances pour que ServiceFilter puisse le résoudre.
Plus d'informations à ce sujet sur https://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/