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

Шаблон NHibernate и Repository

Каков рекомендуемый подход к шаблону Nhibernate + Repository?

Есть так много разных статей и мнений, что я не уверен, какой путь принять. Возьмите эту длинную статью, например. Он дает пример объектов Query, но каждый конкретный репозиторий принимает ISession в своем конструкторе. Что мне нужно для NH-сессий в моем BL (бизнес-уровне)?

  • Создайте кучу репозиториев, каждая из которых имеет кучу определенных методов?
    По-видимому, слишком много работы, потому что BL теперь "разрешено" знать NHibernate (Репозиторий - это новый Singleton)?

  • Создать единый общий репозиторий, но выставить IQueriable<T> и использовать LINQ в BL
    Время от времени возникает запрос, который LINQ-to-NHibernate не сможет обработать (или мне нужно настроить SQL вручную один раз в сотни запросов). Это легко с помощью специальных методов репо, но практически невозможно с кодом, основанным на LINQ. И использование обоих только потому, что LINQ в некоторых случаях нарушается, нонсенс.

  • Объекты запроса
    QueryOver также является NH-специфическим, что означает, что BL снова осознает реализацию DAL.

  • Еще один подход?

Очевидно, что мне нужно иметь возможность управлять транзакциями где-то, возможно, используя паттен-модуль Unit-of-work (хотя есть и много различных реализаций этого).

4b9b3361

Ответ 1

В мире архитектуры программного обеспечения много противоречивых мнений, и многие из них очень обоснованы.

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

2) Использование LINQ с NHibernate является вариантом, но я хотел бы подчеркнуть, что вы должны дать себе возможность вернуться к использованию запросов критериев или HQL, если вы это сделаете. На этом этапе вы можете найти себе множество исключений, вы будете задаваться вопросом, какова была начальная точка абстракции.

3) QueryOver - это безопасная по типу оболочка вокруг запросов критериев, и это только делает их гораздо более привлекательными для меня. Я так часто оказываюсь на том, что я возвращаюсь к критериям чистого контроля, который они предлагают, - часто случается, что мне приходится использовать "магические струны". Это, по сути, сделает NHibernate вашей абстракцией доступа к данным. Фактически, было бы лучше абстракцию, что большинство "репозиториев", потому что большинство из них просто предоставляют методы CRUD... репозиторий должен иметь возможность обрабатывать спецификации запросов (как работает QueryOver).

Что касается транзакций - это зависит от вашей структуры. На самом деле я не считаю его реалистичным или полезным использовать единицу шаблона работы в приложении и скрывать реализацию от него (вы могли бы абстрагировать его - но в чем смысл? - вы действительно собираетесь изменить свой ORM?)

Если вы используете ASP.NET, тогда просто (как минимум) запустите транзакцию в начале запроса, откат на исключениях и фиксацию в конце.

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

Ответ 2

Теперь сайт, похоже, сейчас не работает, но мне очень нравится подход Боба Крейвена и использовал его в некоторых крупных проектах:

http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/ EDIT: версия кеша Google

Он использует generics и шаблон UOW для доступа к данным.

Да, это небольшая боль, когда вам нужно вернуться на SQL, но я использую уровень Data Service, который может абстрагироваться от этого. То есть Уровень обслуживания данных использует общий дао, где это возможно (90% времени), и использует ванильные SQL/другие фреймворки в других местах.