Управление NHibernate ISession с Autofac

У кого-либо есть какие-либо подсказки или лучшие практики относительно того, как Autofac помогают, может управлять Экземпляром NHibernate ISession (в случае приложения MVC ASP.NET)?

16
задан Peter Lillevold 9 May 2010 в 21:28
поделиться

2 ответа

Я не слишком хорошо знаком с тем, как следует обрабатывать сеансы NHibernate. Тем не менее, Autofac имеет отличную обработку времени жизни экземпляра ( область видимости и детерминированное удаление ). Некоторые связанные ресурсы - это эта статья и этот вопрос . Поскольку вы находитесь в области ASP.Net MVC, убедитесь, что вы также изучили материалы по интеграции MVC .

Чтобы проиллюстрировать суть дела, вот краткий пример того, как можно использовать фабричные делегаты Autofac и универсальный Owned , чтобы получить полный контроль над временем жизни экземпляра:

public class SomeController
{
    private readonly Func<Owned<ISession>> _sessionFactory;

    public SomeController(Func<Owned<ISession>> sessionFactory)
    {
        _sessionFactory = sessionFactory;
    }

    public void DoSomeWork()
    {
        using (var session = _sessionFactory())
        {
             var transaction = session.Value.BeginTransaction();
             ....   
        }
    }
}

Настройка контейнера, чтобы заставить это работать, довольно просто.Обратите внимание, что нам не нужно ничего делать, чтобы получить типы Func <> и Owned <> , они автоматически становятся доступными с помощью Autofac:

builder.Register(c => cfg.BuildSessionFactory())
    .As<ISessionFactory>()
    .SingleInstance();
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession());

Обновление: Я считаю, что согласно этому руководству NHibernate время жизни экземпляра сеанса должно соответствовать времени жизни «единицы работы». Таким образом, нам нужен какой-то способ управления как при создании экземпляра сеанса, так и при удалении сеанса.

С Autofac мы получаем этот контроль, запрашивая Func <> вместо типа напрямую. Если не использовать Func <> , потребуется заранее создать экземпляр сеанса до создания экземпляра контроллера.

Далее, по умолчанию в Autofac у экземпляров есть время жизни своего контейнера. Поскольку мы знаем, что нам нужны полномочия для удаления этого экземпляра, как только единица работы будет выполнена, мы запрашиваем экземпляр Owned . В этом случае удаление принадлежащего экземпляра приведет к немедленному удалению базового сеанса.

19
ответ дан 30 November 2019 в 22:23
поделиться

Edit: Похоже, что Autofac и, возможно, другие контейнеры могут правильно определить время жизни. Если это так, то действуйте.

Не стоит использовать ваш IoC-контейнер для прямого управления сессиями. Время жизни вашей сессии должно соответствовать вашей единице работы (границе транзакции). В случае веб-приложения это почти наверняка должно быть время жизни веб-запроса.

Наиболее распространенным способом достижения этого является HttpModule, который одновременно создает сессию и начинает транзакцию, когда начинается запрос, а затем фиксирует, когда запрос завершен. Я бы попросил HttpModule зарегистрировать сессию в коллекции HttpContext.Items.

В вашем IoC контейнере вы могли бы зарегистрировать что-то вроде HttpContextSessionLocator против ISessionLocator.

Я должен упомянуть, что ваша общая обработка ошибок должна находить текущую сессию и автоматически откатывать транзакцию, иначе вы можете совершить половину работы.

0
ответ дан 30 November 2019 в 22:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: