Проектирование репозиториев для DI (внедрение конструктора) для сервисного уровня - PullRequest
6 голосов
/ 07 ноября 2011

Я создаю приложение MVC3, пытаюсь использовать IoC и инжектор конструктора. В моей базе данных (пока) около 50 таблиц. Я использую EF4 (с шаблоном POCO T4) для моего кода ЦАП. Я использую шаблон репозитория, и каждая таблица имеет свой собственный репозиторий. Мои сервисные классы в моем сервисном слое вводятся через эти репозитории.

Проблема: Мои классы обслуживания растут в количестве необходимых им репозиториев. В некоторых случаях я подхожу к 10 репозиториям, и они начинают пахнуть.

Существует ли общий подход к проектированию репозиториев и классов обслуживания так, чтобы сервисам не требовалось так много репозиториев?

Вот мои мысли, я просто не уверен, какой из них правильный:

1) Это признак того, что я должен рассмотреть возможность объединения / группировки моих репозиториев в связанные разделы таблиц, сокращения количества или зависимых репозиториев для класса обслуживания. Однако проблема с этим подходом заключается в том, что он раздувает и усложняет мои репозитории и лишает меня возможности использовать общий интерфейс для всех репозиториев (стандартные методы поиска / обновления данных).

2) Это признак того, что я должен подумать о том, чтобы разбить свои сервисы на группы на основе моих репозиториев (таблиц). Проблема в том, что некоторые из моих методов обслуживания имеют общую реализацию, и разбивка их по классам может усложнить мои зависимости.

3) Это признак того, что я не знаю, что делаю, и что-то в корне неправильно, что я даже не могу увидеть.

ОБНОВЛЕНИЕ: Чтобы узнать, как я реализую EF4 и репозитории, ознакомьтесь с этим примером приложения в codeplex (я использовал версия 1 ). Однако, глядя на некоторые комментарии там (и здесь), похоже, что мне нужно немного больше почитать, чтобы убедиться, что это тот путь, по которому я хочу идти - звучит так, как будто это не так.

Ответы [ 4 ]

6 голосов
/ 07 ноября 2011

Чандермани прав , что некоторые из ваших таблиц могут не являться классами основного домена.Это означает, что вы никогда не будете искать эти данные, кроме как с точки зрения одного типа родительского объекта.В этих случаях вы можете ссылаться на них как на «сложные типы», а не на полноценные сущности, и EF по-прежнему будет заботиться о вас.

Я использую шаблон хранилища, и каждая таблица имеет свою собственнуюрепозиторий

Надеюсь, вы сами не пишете их с нуля.

EF 4.1 уже реализует Шаблон репозитория ( DbSet ) и шаблон единицы работы ( DbContext ).Старые версии тоже так делают, хотя шаблон DbContext можно легко настроить, чтобы обеспечить чистую насмешливую реализацию, изменив эти свойства на IDbSet.

Я видел несколько учебных статей, где люди все еще пишут своисобственный, хотя.Это странно для меня, потому что они обычно не дают обоснования, кроме того факта, что они «реализуют шаблон репозитория».

Написание оболочек для этих репозиториев для таких методов доступа, как FindById, делает егонемного легче получить доступ, но, как вы видели, это большое усилие, потенциально небольшая окупаемость.Лично, если я не нахожу, что есть инкапсуляция интересной предметной логики или сложных запросов, я даже не потрудлюсь и просто использую Linq непосредственно против IDbSet.

Мои классы обслуживания вМой сервисный уровень внедряется в эти репозитории.

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

6 голосов
/ 07 ноября 2011

Если вы посмотрите на шаблон DDD Aggregate Root и попытаетесь просмотреть ваши данные в этом ракурсе, вы поймете, что многие таблицы вообще не имеют независимого существования. Их данные действительны только в контексте их родителя. Большинство операций над ними требуют, чтобы вы также получили родителя. Если вы можете сгруппировать такие таблицы и найти родительский объект \ репозиторий, все остальные дочерние репозитории могут быть удалены. Сложность связывания родительского дочернего элемента, которую до сих пор вы выполняли на бизнес-уровне (при условии, что вы извлекаете родительский и дочерний элементы с помощью независимого репо), не будет перенесена на DAL

Рефакторинг интерфейса Сервиса также является жизнеспособным вариантом, и любые общие функциональные возможности могут быть перемещены в базовый класс и \ или могут быть определены как сервис, который используется всеми вашими существующими сервисами (Is A vs Has A)

1 голос
/ 07 ноября 2011

@ Чандермани имеет хорошее замечание о совокупных корнях. Хранилища не должны обязательно иметь отображение 1: 1 на таблицы.

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

0 голосов
/ 07 ноября 2011

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

...