Поручить 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, у Джереми Миллера есть запись в блоге о том, как он это делает - используя вложенные контейнеры для контроля продолжительности жизни. Пример Джереми, вероятно, излишний, если приложение простое. Вы, вероятно, должны сосредоточиться на внедрении одного сеанса на компонент / команду в вашем приложении.

Другие вопросы по тегам