2016-08-31 2 views
7

Я использую инъекции зависимостей конструктора на основе везде в моем ASP.NET CORE приложения и мне также нужно решить зависимости в моих фильтров действий:Как использовать Action Filters с Injection Dependency в ASP.NET CORE?

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(); 
    } 
} 

Тогда в контроллере:

[MyAttribute(Limit = 10)] 
public IActionResult() 
{ 
    ... 

Если я ставлю ICustomService на конструктор, тогда я не могу скомпилировать свой проект. Итак, как мне суетиться, чтобы получить экземпляры интерфейса в фильтре действий?

+0

Можете ли вы добавить сеттер в свойстве CustomService, чтобы он был доступен для записи? и добавить ICustomService в качестве параметра в конструкторе? –

+1

Возможный дубликат [ASP.Net Core (MVC 6) - Inject service in Action Filter] (http://stackoverflow.com/questions/36109052/asp-net-core-mvc-6-inject-service-into-action -filter) – gilmishal

+0

Возможный дубликат [Как добавить параметр в фильтр действий в asp.net?](http://stackoverflow.com/questions/39181390/how-do-i-add-a-parameter-to -an-action-filter-in-asp-net) –

ответ

8

Если вы хотите избежать шаблона Service Locator, вы можете использовать DI путем инъекции конструктора с помощью TypeFilter.

В вашем использовании контроллера

[TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})] 
public IActionResult() NiceAction 
{ 
    ... 
} 

И ваш ActionFilterAttribute не требуется доступ к экземпляру поставщика услуг больше.

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(); 
    } 
} 

Для меня аннотацию [TypeFilter(typeof(MyActionFilterAttribute), Arguments = new object[] {10})], кажется, неудобно. Чтобы получить более читаемую аннотацию, например [MyActionFilter(Limit = 10)], ваш фильтр должен наследовать от TypeFilterAttribute. Мой ответ How do I add a parameter to an action filter in asp.net? показывает пример такого подхода.

+0

Вы также можете использовать 'IAsyncActionFilter' вместо' IActionFilter', если вам нужна асинхронная –

1

Вы можете использовать Service Locator:

public void OnActionExecuting(ActionExecutingContext actionContext) 
{ 
    var service = actionContext.HttpContext.RequestServices.GetService<IService>(); 
} 

Если вы хотите использовать конструктор использовать инъекции TypeFilter. См. How do I add a parameter to an action filter in asp.net?