Поручить StructureMap создать новую сессию (только при утилизации)
Я использую StructureMap с Nhibernate, и я хотел бы поручить инструменту создавать новый сеанс каждый раз, когда это необходимо, и только если он удаляется.
Я попытаюсь объяснить с помощью некоторого кода (это консольное приложение).
Я создаю свою фабрику сессий таким образом (ConnDb - моя строка подключения):
For<ISessionFactory>()
.Singleton()
.Use(() => new NHSessionFactory(ConnDb, true).SessionFactory);
и это код, который я использую для создания сеанса:
For<ISession>()
.Singleton()
.Use(x => x.GetInstance<ISessionFactory>().OpenSession());
Все работает как положено, когда я не располагаю сессией, но я хотел бы иметь возможность сделать что-то вроде этого:
using (session)
{
using (var tx = session.BeginTransaction())
{
// DO SOMETHING
tx.Commit();
}
}
using (session)
{
using (var tx = session.BeginTransaction())
{
// DO SOMETHING
tx.Commit();
}
}
Я попытался изменить код для сеанса, например так:
For<ISession>()
.AlwaysUnique()
.Use(x => x.GetInstance<ISessionFactory>().OpenSession());
но я заметил, что теперь создается новый сеанс, даже если есть один активный. В моей ситуации я ссылаюсь на другой компонент (Rhino.Security), который разрешает ISession с помощью локатора службы.
1 ответ
Сессия должна быть уничтожена создателем Сессии, а не каким-либо клиентом. Вы должны рассмотреть возможность пересмотра своей архитектуры, чтобы сессия создавалась и располагалась в одной и той же области видимости.
Срок службы сеанса должен быть ограничен, чтобы соответствовать компоненту, который его использует. Имея один глобальный сеанс (как с вашей попыткой синглтона), сеанс будет содержать ссылки на все сущности, к которым вы обращались в любое время в течение срока службы вашего приложения - эффективно расходуя вашу память. Кроме того, если ваша сессия выдает исключение, она будет в неопределенном состоянии и приведет к остановке всего вашего приложения.
Прочитайте статью Айенде в журнале MSDN о том, как использовать NHibernate с настольными приложениями. Совет, который он дает, с большой вероятностью также применим к вашему сценарию.
Когда дело доходит до обработки сессий с помощью StructureMap, у Джереми Миллера есть запись в блоге о том, как он это делает - используя вложенные контейнеры для контроля продолжительности жизни. Пример Джереми, вероятно, излишний, если приложение простое. Вы, вероятно, должны сосредоточиться на внедрении одного сеанса на компонент / команду в вашем приложении.