Ну, во-первых, я пропустил пункт о глобальных фильтрах.
Конечно, это зависит от того, как вы создаете экземпляр фильтра.
- Когда вы определяете фильтр как атрибут, он создается ввремя выполнения во время вызова действия контроллера и легко внедряет в настоящее время доступный
ISession
экземпляр. - Но когда вы пытаетесь добавить его к
GlobalFilterCollection
- вы должны (по умолчанию) создать его экземпляр следующим образом: filters.Add(new CustomActionFilter())
.Это означает, что конструктор CustomActionFilter
вызывается немедленно (при запуске приложения) и пытается разрешить сеанс.Как вы можете себе представить, вы не можете использовать один и тот же ISession
для всех запросов к вашему приложению MVC.Поэтому вы реализуете шаблон Session-per-Request .И должен вводить новый экземпляр для каждого запроса.
Самое простое, что нужно сделать, это переместить ISession
разрешение (this.Session = ObjectFactory.GetInstance<ISession>();
на OnActionExecuting(...)
метод.
Гораздо сложнееМожно создать собственный тип CustomFilterCollection
и предоставить собственную инфраструктуру регистрации фильтров.
Обновление: Первое предлагаемое решение неприменимо. Проблема в том, что фильтр хранит состояние в своемОднако существуют опции:
- Использовать фильтры как атрибуты, а не как элементы
GlobalFilterCollection
. - Реализовать управление параллелизмом состояний внутри самого фильтра (т.е. хранить
Sessions
для всехзапрашивает в свойстве коллекции глобального фильтра и как-то им управляет.) Плохой, вонючий подход imho, и не масштабируемый. Управление временем жизни сеанса не должно принадлежать фильтрам. - Использовать другую систему регистрации фильтров (т.е. свернуть собственную реализациюиз
IFilterProvider
- возьмите FluentFilters в качестве примера того, как это сделать, или просто используйте его).
Кроме того, лучшеотделить ActionFilter
с от FilterAttribute
с.