Лучший способ использовать NHibernate с моделью хранилища - PullRequest
8 голосов
/ 16 марта 2009

У меня есть класс репозитория, который определяет некоторые основные методы Get / Save / Delete. Внутри них я использую NHibernate для работы над своими бизнес-объектами. Например:

Public Class SecurityRepositoryNHibImpl : Implements ISecurityRepository
    Public Function GetUser(ByVal UUID As System.Guid) As Entities.User Implements ISecurityRepository.GetUser
        Dim eUser As Entities.User
        Using session As ISession = NHibernateHelper.OpenSession()
            eUser = session.Get(Of Entities.User)(UUID)
        End Using
        Return eUser
    End Function
End Class

Однако в моем классе User у меня есть некоторые свойства и коллекции других объектов, которые в идеале я бы хотел загружать ленивыми. Но, разумеется, ISession создается и размещается в репозитории, поэтому я предполагаю, что помимо этого, когда я пытаюсь получить доступ к этим свойствам, я получаю сообщение об ошибке «Не удалось инициализировать прокси-сервер без сеанса».

Мой единственный вариант - отключить отложенную загрузку при использовании репозиториев? Или возможно (или просто глупо) каким-то образом включить сеанс в область действия на бизнес-уровне?

Мне действительно нравится модель репозитория, и NHibernate растет (после многих начальных разочарований, пытаясь заставить его работать), так что, как вы, гуру, нашли лучший способ использовать их вместе?

Я довольно плохо знаком с NHibernate и моделями репозитория в целом (на работе мы по-прежнему в основном используем VB6!), Так что простите, что может быть глупым вопросом. Благодаря.


@ mookid: Спасибо, чувак, это действительно полезно, но я мог бы оставить его открытым немного дольше. Это серверная часть веб-службы WCF, и все функции будут зависеть от контекста вызова, поэтому срок службы сеанса каждого вызова будет хорошим. Просто не знаю, как заставить такое работать на бизнес-уровне, в идеале я не хочу, чтобы бизнес-объекты имели непосредственный интерфейс с любыми классами NHibernate. Я предполагаю, что какая-то обертка для сессии NHibernate по крайней мере абстрагирует это ... Хм, ты как минимум поставил меня на правильный путь.


Похоже, ключевое слово здесь - «Единица работы», для которой существует тонна ресурсов в сети по отношению к NHibernate. В частности, обратите внимание на реализацию Айенде в Rhino Commons и его веб-трансляцию архитектуры приложений (№ 9 в Hibernating Rhinos) , очень информативную. Сначала я был в замешательстве, потому что я, хотя включение «Единицы работы» в бизнес-уровень смешивало проблемы, , но вскоре меня исправили.

1 Ответ

12 голосов
/ 16 марта 2009

Создание вашей ISession и ее явное размещение внутри ваших репозиториев, как это хорошо для небольших и очень простых проектов, - но, как вы выяснили, у вас не получается, когда вы захотите использовать некоторые интересные функции, которые поддерживает NHibernate.

Вы, вероятно, должны позволить образу жизни сеанса управлять чем-то за пределами ваших хранилищ - например, если вы работаете с веб-приложениями ASP.NET, вы можете сохранить сеанс в текущем запросе (HttpContext.Current.Items, если я правильно помню) на время веб-запроса, а затем зафиксировать и утилизировать в конце запроса ( или откат в случае возникновения исключения).

Я не знаю лучшего способа управления образом жизни вашего сеанса в приложениях ASP.NET, но должен быть какой-то способ, чтобы код вызывался в начале и в конце каждого запроса. В ASP.NET MVC это может быть легко достигнуто путем извлечения всех ваших контроллеров из базового контроллера, который переопределил свои OnActionExecuting и OnActionExecuted методы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...