Управление жизненным циклом сессии NHibernate в веб приложении (ASP.NET) - CodeHelper

Управление жизненным циклом сессии NHibernate в веб приложении (ASP.NET)

2

Как правильно организовать открытие/закрытие сессии NHibernate в приложении на ASP.NET

Новые ответы


0

Я обычно в конструкторе веб приложения (класс, который наследуется от System.Web.HttpApplication) добавляю следующий код:

BeginRequest += (sender, args) =>
{
    try
    {
    	CurrentSession = NHibernateManager.OpenSession();
    }
    catch (Exception ex)
    {
    	_log.Error(ex);
    	throw;
    }
};
EndRequest += (sender, args) =>
{
    if (CurrentSession != null) CurrentSession.Dispose();
};

Который при каждом новом запросе создает сессию. И при выполнении запроса уничтожает её. Сессия NHibernate хранится в контексте текущего запроса, и доступна везде в приложении. Для доступа к ней я использую StructureMap, но это уже детали.

    public static ISession CurrentSession
    {
        get { return (ISession)HttpContext.Current.Items["current.session"]; }
        set { HttpContext.Current.Items["current.session"] = value; }
    }
2

Для веб-приложения логично привязать время жизни сессии NHibernate ко времени жизни запроса (request). Новая сессия открывается при запросе к серверу и закрывается когда запрос обработан и пользователю вернулся ответ. Практически все web-каркасы поддерживают механизм слежения за жизненным циклом запроса. В ASP.NET можно использовать модули и хендлеры.

Spring.NET уже имеет в своей поставке специальный модуль для этих целей — OpenSessionInViewModule. Сам механизм привязки сессии к запросу в терминологии Spring называется open session in view (OSIV) pattern.

2

NHibernate, как и большинство ORM-библиотек, использует шаблон UnitOfWork, чтобы управлять жизненным циклом таких объектов как сессия и транзакция. Обычно, чтобы не привязывать логику отображения к логике ORM, в приложениях пишется собственный класс UnitOfWork, являющийся оберткой над сущностями ORM (NHibernate). Этот класс выглядит примерно так:

public class UnitOfWork: IUnitOfWork, IDisposable {
    public UnitOfWork(){
        // Создаем общую сессию NHibernate
    }

    public void Dispose(){
        // Комитим изменения сессии или просто закрываем ее
    }
}

Его использование в логике отображения:

using(CreateUnitOfWork()){
    var item = new Item();
    ItemRepository.Add(item);
}

v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.