NHibernate Session удаляется при каждом вызове метода службы wcf - PullRequest
2 голосов
/ 07 июля 2010

Я использую Wcf в Sharp Architecture. Я настроил свой проект, следуя примеру северного ветра, используя WcfSessionStorage и т. Д. У меня есть метод в сервисе wcf, который получает список бизнес-объектов с помощью Repository <>. GetAll (). Я тестирую метод обслуживания с помощью WcfTestClient. Когда метод вызывается в первый раз, все работает нормально. Однако при последующем вызове я получаю следующее исключение для репозитория <>. Метод GetAll ()

[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'

Похоже, что сессия NHibernate удаляется после каждого вызова. Я решил эту проблему, украсив свой сервис следующим атрибутом

[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}

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

Спасибо Набиль

Ответы [ 2 ]

2 голосов
/ 07 июля 2010

Самый простой способ - каждый раз создавать новый экземпляр, и это не дорогой процесс, потому что создание нового объекта в .NET занимает 0,00000000000000001 секунду (я читал это в блоге Аянде или где-то еще).

Я использую Autofac DI в своих проектах и ​​обычно использую ISession в качестве контейнера (по одному на запрос). И затем каждый класс, который использует (прямо или косвенно) ISession, должен быть ограничен областью контейнера или ниже (фабричная область == каждое использование класса get - это новый экземпляр). Если класс, который использует ISession, имеет большую область действия (сессия = = singleton), вы столкнетесь с проблемами, которые у вас есть в данный момент.

Если ваш сервис одноразовый: При первом запуске служба создается, эта служба использует ISession, которая должна иметь область видимости контейнера, и находится при первом запуске. Следующий запрос к сервису (сервис в настоящее время создан) все еще имеет ссылку на созданный ISession (который был закрыт по предыдущему завершающему запросу), поэтому теперь он закрыт.

Я не рекомендую использовать ту же сессию IS, которую вы открываете / закрываете (это не рекомендуется в документации NHibernate), просто используйте область контейнера (у меня есть и у меня нет проблем с производительностью), или вам следует создать ISession вручную для каждого метода в вашем сервисе, например:

using(ISession s = ISessionFactory.OpenSession())
     using(ITransaction t = .....)
....

Но это совсем не хорошо ...

1 голос
/ 07 июля 2010

Пожалуйста, посмотрите на мой ответ на мой похожий вопрос: WCF / S # arpArch: базовая ISession закрывается после первого вызова в запросе .

@ dmonlord прав, что создание дополнительных экземпляров сеанса в рамках одного и того же запроса в этом случае обходится очень дешево.

...