Подтвердить что ты не робот

NHibernate с или без репозитория

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

Реальный вопрос: разумно ли абстрагировать NHibernate с использованием шаблона репозитория или не?

Похоже, что единственная причина абстрагирования - оставить себе возможность заменить NHibernate другим ORM, если это необходимо. Но создание репозиториев и абстрагирование запросов похоже на добавление еще одного слоя и большую часть сантехники.

Один из вариантов заключается в том, чтобы использовать exose IQueryable<T> для бизнес-уровня и использовать LINQ, но из моего опыта поддержка LINQ до сих пор не полностью реализована в NHibernate (запросы просто не всегда работают должным образом, и я ненавижу проводить время на отладка структуры).

Хотя ссылка на NHibernate в моем бизнес-слое причиняет мне боль, он должен быть абстракцией доступа к данным сам по себе, правильно?

Что вы думаете об этом?

4b9b3361

Ответ 1

Хорошие ответы. Я тоже думал о них несколько дней назад.

Собственно, попробуйте NHibernate 3.0 alpha (или текущую магистраль), его новый поставщик LINQ намного больше, чем предыдущий. (До сих пор я нашел только один метод, который не работает, но можно подключить свой собственный механизм, если вы столкнулись с чем-то, что он не поддерживает по умолчанию.) У меня не было проблем (пока?) С использованием текущего ствола. Вы можете найти "ночную" версию на http://www.hornget.net/packages/ сайте вместе с созданием FluentNHibernate против него. Свободный уровень действительно повышает вашу производительность, если вы знаете, как его использовать. Сообщество SO действительно помогло мне с этим.

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

Причина абстрагирования не только полезна, потому что тогда вы можете заменить NHibernate позже другим ORM, но это хорошая практика из-за концепции, называемой Разделение проблем. Уровень вашей бизнес-логики не должен заботиться и не знать о том, как получить доступ к данным, с которыми он работает. Это упрощает поддержку приложения или его различных слоев, что также упрощает работу в команде: если X создает уровень доступа к данным, а Y пишет бизнес-логику, им не нужно подробно разбираться в деталях друг друга.

Выявление IQueryable<T> - очень хорошая идея, и именно это делает много реализаций репозитория прямо сейчас. (И мне тоже, хотя я предпочел написать его в статическом классе.) И, конечно, вам нужно будет выставить некоторые методы для вставки или обновления объекта или методов для начала и совершения транзакций, если хотите. (BeginTransaction должен просто вернуть IDisposable, чтобы избежать утечки интерфейса NHibernate, и все будет хорошо.)

Я могу дать вам несколько советов: ознакомьтесь с инструментами SharpArchitecture или FubuMVC Contrib, чтобы получить некоторые идеи о том, как это сделать правильно, и это как я его решил.

Ответ 2

Я бы просто сказал большое ДА! имеют шаблон хранилища, сохраняйте абстракцию!

Ответ 3

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

Другая точка репозитория. Некоторые люди предлагают не делать его общим и иметь идентификацию типа на уровне метода (т.е. Repository.Load). Это, однако, предполагает, что будет один репозиторий, который знает, как справляться со всеми типами. Я не большой поклонник этого понятия одного монолитного репозитория. Что делать, если вы имеете дело с несколькими базами данных? Или несколько механизмов сохранения? Или некоторые типы данных остаются довольно статичными и могут кэшироваться, но другие не могут. Вот почему мне нравится отдельный экземпляр репозитория для каждого типа.