nhibernate / Structuremap ObjectFactory.GetInstance ISession не удается - PullRequest
0 голосов
/ 30 марта 2011

Я использую этот метод , для моего приложения asp.net mvc он прекрасно работает.Но когда я использую его в глобальном фильтре:

public class CustomActionFilter: ActionFilterAttribute
{
    public ISession Session { get; set; }

    public CustomActionFilter()
    {
        this.Session = ObjectFactory.GetInstance<ISession>();
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //call ISession.CreateQuery(...); query.UniqueResult<SomeObject>();

    }        
}

, это выдает ошибку ' Session is closed '.Любые подсказки, что я делаю неправильно?

Заранее спасибо!

1 Ответ

0 голосов
/ 30 марта 2011

Ну, во-первых, я пропустил пункт о глобальных фильтрах.

Конечно, это зависит от того, как вы создаете экземпляр фильтра.

  • Когда вы определяете фильтр как атрибут, он создается ввремя выполнения во время вызова действия контроллера и легко внедряет в настоящее время доступный 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 с.

...