2014-11-23 2 views
2

Я следующий глобальный код фильтра:Как получить обновленный объект с NHibernate сессии в Global Filter

public class UserAuthorizationFilter : FilterAttribute, IAuthorizationFilter 
{ 
    private readonly IAdministratorService _administratorService; 

    public UserAuthorizationFilter() 
    { 
     _administratorService = IoCFactory.Container.GetInstance<IAdministratorService>(); 
    } 

    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     string username = HttpContext.Current.User.Identity.Name; 
     IRequestMessage<string> request = MessageFactory.BuildRequestFor(username, username); 
     Administrator administrator = _administratorService.GetDetailByName(request).Data; 

     filterContext.Controller.ViewBag.Username = username; 
     filterContext.Controller.ViewBag.IsAdmin = administrator != null; 

     if (administrator != null) 
     { 
      bool isManageRole = administrator.Roles.Any(r => r.IsManageRole); 
      bool isManageAdministrator = administrator.Roles.Any(r => r.IsManageAdministrator); 
      bool isManageReviewer = administrator.Roles.Any(r => r.IsManageReviewer); 

      filterContext.Controller.ViewBag.IsManageRole = isManageRole; 
      filterContext.Controller.ViewBag.IsManageAdministrator = isManageAdministrator; 
      filterContext.Controller.ViewBag.IsManageReviewer = isManageReviewer; 

     } 
    } 
} 

и я добавить этот фильтр в случае Application_Start из global.asax:

GlobalFilters.Filters.Add(new UserAuthorizationFilter(), 0); 

Когда Я обновляю свойство роли администратора, например IsManageRole от true до false, данные были успешно обновлены до базы данных. Тем не менее в UserAuthorizationFilter свойство свойства в объекте администратора не обновляется, его нагрузка true значение. Я попытался позвонить sessionFactory.Evict(typeof(Role)), session.Clear(), но не нашел удачи. Однако данные не будут загружать новое обновленное свойство Role. свойство было обновлено, если я перезапущу веб-приложение.

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

ответ

1

Было бы интересно здесь, чтобы увидеть implemetnation в IAdministratorService, как это делает кэш результаты вызова метода .GetDetailByName(request).

Дело в том, что фильтры ASP.NET MVC можно обрабатывать как: singleton. См.: Are ActionFilterAttributes reused across threads? How does that work?:

... В ASP.NET MVC 3 фильтры кэшируются более агрессивно. Поэтому любые пользовательские фильтры действий, которые ненадлежащим образом сохраняют состояние экземпляра, могут быть разбиты ...

Давайте подумаем о них, что они создаются один раз, они живут вечно без «перестройки». То есть нет нового IoC/DI через конструктор.

Может быть больше способов, как обойти это.

I. грязный путь был бы назвать IoCFactory.Container.GetInstance<IAdministratorService>(); в каждом OnAuthorization(). Скорее всего, это вернет новую новую услугу с доступом к новым данным в текущем сеансе. Он должен работать ... но: Service Locator is an Anti-Pattern Mark Seemann

II. См. Эту статью Брэда Уилсона о предоставлении filters in MVC и в основном раздел: Добавление инъекции зависимостей к фильтрам. В двух словах каждый атрибут обогащается инъекцией установщика, используя Unity IoC. увидеть фрагмент поставщика фильтра:

var attributes = base.GetActionAttributes(controllerContext, 
               actionDescriptor); 
foreach (var attribute in attributes) { 
    _container.BuildUp(attribute.GetType(), attribute); 
} 

III. Я бы пошел с некоторым общим «кэшем приложений», представленным шаблоном поставщика. (Несмотря на то, что Provider is not a pattern автор Mark Seemann).

  • Фильтр будет общаться с некоторыми SecurityManager.
  • Будет один синглтон SecurityProvider, берущий свежие данные из текущих сеансов (сессий) и их кеширование.
  • кэш будет очищен после некоторого разумного периода времени (минут для безопасности я бы сказал)
  • системы Eventing на объектах «безопасности» также запустит cache.Clear()
  • АОП Mvc фильтр будет иметь доступ к вплоть до настоящего времени данные безопасности
+0

Спасибо, этот ответ действительно помогает мне фиксировать мой DI для фильтров с использованием 'IFilterProvider'. Кроме того, я сделал взломанные изменения, как работает мой IoC, теперь я использую 'IDependencyResolver'. Также у меня есть этот объект администрирования с использованием хранилища сеансов. –

+0

Замечательно видеть, что сэр! Наслаждайтесь потрясающим NHibernate;) –

Смежные вопросы