1

Я внедрил IAuthenticationFilter, чтобы создать пользовательский. в конструкторе Я использую structureMap, чтобы получить экземпляр моего IUnitOfWork. эта логика проверки подлинности для проверки статуса пользователя в базе данных и ....asp.net MVC: использовать unitOfWork внутри пользовательского аутентификацииAttribute, когда ActionFilters не являются для каждого запроса?

IUnitOfWork uow; 

public CustomAuthenticatationAttribute() 
{ 
    this.uow = ObjectFactory.GetInstance<IUnitOfWork>(); 
} 

Я настроил StructureMap служить IUnitOfWork HttpContextScoped.

x.For<IUnitOfWork>().HttpContextScoped().Use(() => new MyDbContext()); 

но потом произошло что-то странное. Я удалил пользователя в одном действии, но когда AuthenticationFilter выполняется при другом действии, экземпляр unitOfWork по-прежнему возвращает пользователя! Я искал в Интернете в течение нескольких часов, и я пришел к этому:

Are ActionFilterAttributes reused across threads? How does that work?

Короче говоря, он говорит, что фильтры кэшируются и используются по запросам!

Теперь я в замешательстве. как с этим бороться? я должен отказаться от использования unitOfWork и вернуться к using(var context = ....)? или есть правильный способ использования unitOfWork внутри фильтров.

Я нашел решение здесь

https://gist.github.com/ivanra/9019273

Он заменяет DefaultFilterProvider и я предпочитаю, чтобы избежать этого, если это возможно.

ответ

1

Решение, которое вы обнаружили с подавлением кеширования в FilterProvider, на самом деле является тем же решением, что и библиотеки интеграции MVC для использования Autofac и Simple Injector.

Но поведение кеширования атрибутов - это просто one of the many reasons, почему введение зависимостей в атрибутах на самом деле является плохой идеей.

Лучшим решением является IMO для перехода на passive attributes, если вы можете или, по крайней мере, инкапсулировать логику атрибутов и ее зависимости в компонент и не выполнять ничего, кроме решения и выполнения этого компонента в методе OnActionExecuting. Например:

public class CustomAuthenticatationAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
     var action = 
      ObjectFactory.GetInstance<IActionFilter<CustomAuthenticatationAttribute>>(); 

     action.OnActionExecuting(this, context); 
    } 
}