Внедрение репозитория в ActionFilter

#c# #dependency-injection #.net-core #action-filter

#c# #внедрение зависимостей #.net-ядро #действие-фильтр

Вопрос:

Я пытаюсь внедрить репозиторий в фильтр действий, но получаю следующую ошибку:

При обработке запроса произошло необработанное исключение. Исключение InvalidOperationException: не удается разрешить службу для типа ‘…ISqlRepository’ при попытке активации ‘…MyActionFilterAttribute’.

Я пытаюсь отсюда следовать шаблону Стива Смита. Все работает нормально, пока я не добавлю ссылку ISqlRepository в конструктор.

Вот соответствующие фрагменты кода:

Startup.cs

 services.AddScoped<MyActionFilterAttribute>();
  

MyActionFilterAttribute.cs (Я понимаю, что здесь я реализую IResultFilter. Я просто пытаюсь придерживаться как можно ближе к примеру).

 public class MyActionFilterAttribute: IResultFilter
    {
        private ILogger _logger;
        private ISqlRepository _sql;
        public MyActionFilterAttribute(ILoggerFactory loggerFactory, ISqlRepository sql)
        {
            _logger = loggerFactory.CreateLogger<LoaderActionFilterAttribute>();
            _sql = sql;
        }
  

MyController.cs

 [Route("api/[controller]")]
    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public class MyController: Controller
  

Комментарии:

1. Вы зарегистрировали свой класс репозитория?

Ответ №1:

Вам нужно будет зарегистрировать свой репозиторий, как обычно, в IoC:

 services.AddScoped<ISqlRepository,SqlRepository>();
  

Затем вам нужно будет сделать property injection с атрибутом.

Выглядит так —

 public class MyActionFilterAttribute: IResultFilter
{
    public static Func<ISqlRepository> GetSqlRepo;

    private ISqlRepository _sql;

    public MyActionFilterAttribute()
    {
        _sql = GetSqlRepo();
    }
}
  

При запуске у вас будет доступ к вашей коллекции сервисов, поэтому вы можете выполнить следующее

 MyActionFilterAttribute.GetSqlRepo = () => services.GetService<ISqlRepository>()
  

Ответ №2:

Вам нужно добавить ISqlRepository в свои сервисы:

 services.AddScoped<ISqlRepository,SqlRepository>();
  

Причина, по которой образец проекта, на который ссылается ссылка, не должен был этого делать, заключается в том, что ILoggerFactory добавляется через фреймворк.

Комментарии:

1. Спасибо, ребята! Я выбрал решение @mxmissile, и, похоже, оно работает!

2. Как это приводит к получению экземпляра вашего репозитория в атрибуте?