Действительно ли статический репозиторий является правильным способом использовать NHibernate?

Я потратил остальную часть вечера, читая вопросы о StackOverflow и также некоторые записи в блоге и ссылки о предмете. Все они оказались очень полезными, но я все еще чувствую, что они действительно не отвечают на мой вопрос.

Так, я разрабатываю простое веб-приложение. Я хотел бы создать допускающий повторное использование уровень доступа к данным, который я могу позже снова использовать в других решениях. 99% из них будут веб-приложениями. Это, кажется, хорошее оправдание за меня изучить NHibernate и некоторые шаблоны вокруг этого.

Мои цели следующие:

  • Я не хочу, чтобы слой бизнес-логики знал ЧТО-ЛИБО о внутренних работах базы данных, ни сам NHibernate.
  • Я хочу, чтобы слой бизнес-логики имел наименее возможное количество предположений об уровне доступа к данным.
  • Я хочу уровень доступа к данным, максимально упрощенный и простой в использовании. Это будет простым проектом, таким образом, я не хочу сверхусложнять что-либо.
  • Я хочу, чтобы уровень доступа к данным был максимально ненавязчив.

Будет все это в памяти, я решил использовать популярный шаблон репозитория. Я читал об этом предмете на этом сайте и на различных блогах dev, и я слышал некоторый материал о шаблоне единицы работы.

Я также озирался и проверил различные реализации. (Включая FubuMVC contrib, и SharpArchitecture и материал на некоторых блогах.) Я узнал, что большинство из них работает с тем же принципом: Они создают "единицу работы", которая инстанцируют, когда репозиторий инстанцируют, они запускают транзакцию, действительно наполните, и фиксация, и затем запуститесь снова и снова. Так, только один ISession на Repository и вот именно. Затем клиентский код должен инстанцировать репозитория, действительно наполните им и затем расположите.

Этот шаблон использования не удовлетворяет мои потребности того, чтобы быть максимально упрощенным, таким образом, я начал думать о чем-то еще.

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

Так, я придумал это:

У меня есть внутренний статический названный класс NHibernateHelper. Во-первых, этому назвали статическое свойство CurrentSessionFactory, который на первый вызов, инстанцирует фабрики сессии и хранит его в статическом поле. (Один ISessionFactory на одного AppDomain достаточно хорошо.) Затем что еще более важно, это имеет a CurrentSession статическое свойство, которое проверяет, существует ли ISession связанный с текущим контекстом сессии, и в противном случае создает один и связывает его, и это возвращается с ISession связанный с текущим контекстом сессии.

Поскольку это будет использоваться главным образом с WebSessionContext (таким образом, один ISession на HttpRequest, хотя для модульных тестов, я настроил ThreadStaticSessionContext), это должно работать беспрепятственно. И после создания и привязки ISession, это сцепляет обработчик событий с HttpContext.Current.ApplicationInstance.EndRequest событие, которое заботится о чистке ISession после того, как запрос заканчивается. (Конечно, это только делает это, если это действительно работает в веб-среде.)

Так, со всем этим настроенным, NHibernateHelper будет всегда мочь возвратить допустимое ISession, таким образом, нет никакой потребности инстанцировать экземпляра Репозитория для "единицы работы" для работы правильно. Вместо этого Repository статический класс, который работает с ISession от NHibernateHelper.CurrentSession свойство, и выставляет функциональность через это общими методами.

Так, в основном я закончил с двумя очень ленивыми одиночными элементами.

Мне любопытно, что Вы думаете об этом? Действительно ли это - допустимый образ мыслей или является мной полностью от дорожки здесь?

Править:
Я должен указать, что класс NHibernateHelper является внутренним, так в значительной степени невидимым для потребителей репозитория.

Другая идея, чтобы к intoduce внедрению зависимости в решение, должен сделать интерфейс названным IDataProvider, и инстанцируйте одного экземпляра этого на первый вызов к Repository класс. (Однако код реализации должен смочь заботиться понятие контекста также.)

РЕДАКТИРОВАНИЕ 2:
Кажется, что многие люди как моя идея, но существует все еще слишком мало мнений об этом в ответах.
Я могу предположить, что это - правильный способ использовать NHibernate, затем?:P

13
задан Venemo 9 September 2012 в 09:14
поделиться

2 ответа

Как бы то ни было, Sharp Architecture делает более или менее именно то, что вы предлагаете. В итоге он доставляет один сеанс для каждого HTTP-запроса (точнее, один сеанс для каждой базы данных на каждый HTTP-запрос). Ваш подход, безусловно, действителен, и он также обеспечивает один сеанс на запрос. Я предпочитаю более чистый объектно-ориентированный подход SharpArch через DI, а не статические репозитории и вспомогательный класс.

2
ответ дан 2 December 2019 в 02:18
поделиться

Мы смешали приложения ASP.NET/Windows Forms, и лучшее решение, которое я нашел, - это внедрение зависимостей вручную через конструктор репозитория. То есть каждый класс репозитория имеет единственный общедоступный конструктор, которому требуется ISession. Это позволяет приложению полностью контролировать границы единицы работы и транзакции. Это просто и эффективно. У меня также есть очень маленькая вспомогательная сборка NHibernate, которая настраивает фабрики сеансов и предоставляет методы для открытия обычного или контекстного сеанса.

В S # arp Architecture мне нравится много вещей, и я думаю, что стоит изучить, как она работает, но я обнаружил, что она слишком продумана для моих вкусов.

1
ответ дан 2 December 2019 в 02:18
поделиться
Другие вопросы по тегам:

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