Во-первых, будьте ясны в отношении своей цели.Шаблон репозитория имеет (как минимум) 3 основных причины существования:
1) Абстрагирование слоя данных.Что касается EF, то если это ваша цель, то шаблон репозитория больше не выгоден.Попытка абстрагировать приложения от Entity Framework - гораздо больше проблем, чем оно того стоит.В конечном итоге вы получите либо / или урезанный DAL, в котором нет ничего удивительного в том, что EF может предоставить, либо неэффективный / медленный, либо очень сложный набор методов репозитория с выражениями и другими неприятностями в качестве параметров.Попытки абстрагировать ваше приложение от EF (на случай, если вы захотите, например, перейти на другой ORM) бессмысленно.Примите EF так же, как вы приняли бы тот факт, что вы пишете свое заявление в .Net.Чтобы абстрагировать EF до такой степени, что его можно заменить, вы также можете не использовать его, потому что вы не увидите никаких преимуществ, которые EF может на самом деле предоставить.
2) Для упрощения тестирования бизнес-логики.IMO Это все еще допустимый аргумент для репозиториев с Entity Framework.Да, EF DbContexts может быть высмеянным, но это все еще грязный бизнес.Пересмешивать репозитории не сложнее, чем любая другая зависимость.
3) служить привратником домена.Шаблоны, такие как DDD, пытаются заблокировать действия с данными в объектах и сервисах домена.Шаблон репозитория может помочь с этим при использовании EF, чтобы помочь содержать методы, которые отвечают за манипулирование доменом.Для чистого DDD я бы не рекомендовал их, хотя я бы не рекомендовал использовать Entities в качестве объектов домена DDD.Я использую шаблон репозитория для управления аспектами CRUD в аспектах CR и D. и полагаюсь на модели представлений для инкапсуляции логики домена вокруг U.
Шаблон репозитория, который я нашел наиболее полезным для обслуживания точек 2& 3 состоит в том, чтобы покончить с очень распространенной концепцией универсальных репозиториев, и скорее относиться к репозиторию более в соответствии с тем, как вы относитесь к контроллеру в MVC.За исключением случаев, когда между View и Model, между Model и Data.Репозиторий - это класс, который обслуживает контроллер (в MVC), поскольку он отвечает за создание, чтение (на уровне ядра) и удаление сущностей.Этот шаблон очень хорошо работает в сочетании с единицей работы.(https://github.com/mehdime/DbContextScope - это реализация, которую я принимаю.)
При создании объекта он отвечает за обеспечение предоставления всех необходимых (ненулевых) значений и ссылок, возвращая объект, связанный сDbContext, готов к работе.Эффективно предприятие сущности.Вы можете поспорить о разделении интересов, хотя, учитывая, что репозиторий уже имеет доступ к DbContext для извлечения связанных сущностей, это случай, когда он в значительной степени является лучшим местом для работы.
В Считывающих сущностях он предоставляет базовую ссылку надалее запрашивать объекты, предоставляя IQueryable<TEntity>
, применяя правила базового уровня, такие как .Where(x => x.IsActive)
для сценариев мягкого удаления, или фильтры для аутентификации / авторизации / аренды на основе зависимостей, которые, например, могут выявить текущего пользователя.Предоставляя IQueryable
, вы сохраняете реализацию репозитория простой и предоставляете потребителю (контроллеру) контроль над тем, как используются данные.Это может использовать отложенное выполнение для:
- Выбор только данных, необходимых для моделей представления.
- Выполнение подсчетов и существующих проверок.(
.Any()
) - Настроить логику фильтрации по структуре объекта для конкретного варианта использования.
- Выполнить разбиение на страницы.
- Получить столько (.ToList (), .Take()) или как можно меньше (.SingleOrDefault (), .FirstOrDefault ()) данных.
Методы чтения чрезвычайно легко смоделировать, и поэтому объем реализации репозитория достаточно мал.Потребители должны знать, что они имеют дело с сущностями, и иметь дело с нюансами EF и это прокси, но потребитель является хранителем отдела работы (продолжительности жизни DbContext) так скрывая этот факт от него довольно спорного вопроса,Передача сложных выражений запросов в методы репозитория в качестве параметров оставляет потребителей в равной степени ответственными за знание нюансов EF.Выражение, которое вызывает закрытый метод, передаваемый в универсальный репозиторий для перехода в предложение Where, будет так же быстро разрушать вещи.Если вы спуститесь по этому маршруту, выполните пункт № 1 выше, не абстрагируйте EF от вашего приложения.
При удалении объекта он обеспечивает правильное управление объектами и их ассоциациями, будь то жесткое или мягкое удаление.
Я избегаю универсальных репозиториев, потому что так же, как контроллер (и представление) будет иметь дело с любым количеством связанных моделей представления домена, это означает, что им потребуется иметь дело с рядом связанных объектов данных.Операции против какой-либо одной сущности будут неизменно связаны с операциями против других иждивенцев.В универсальных репозиториях это разделение означает: а) постоянно растущее число зависимостей и б) универсальные методы, которые выполняют тривиальную дрянь, и много пользовательского кода для обработки значимых вещей, или сложный код, чтобы попытаться упростить его в общем (базовом) виде,Наличие одного репозитория на контроллер и, возможно, некоторых действительно общих общих репозиториев для общих объектов.(например, поиск). Мои репозитории специально разработаны для обслуживания одной области приложения и имеют только одну причину для изменения.Конечно, может быть 2 или более экранов, которые требуют одинакового поведения от репозитория, но по мере развития этих аспектов приложения или службы их репозитории могут при необходимости обновляться / оптимизироваться без побочных эффектов.SRP и KISS легко превосходят DNRY.
Общие классы в целом имеют свое применение, но почти в любом случае, когда я вижу, что разработчики пишут их, я бы сказал, что это преждевременная оптимизация.Начните с неуниверсальных реализаций, затем, по мере развития продукта, оптимизируйте обобщенные в код, а не пытайтесь проектировать архитектуру вокруг них.Результатом почти всегда является осознание того, что вам необходимо де-оптимизировать их или получить «умный» подход к обходу обнаруженных ограничений, когда шаблоны препятствуют развитию.
В любом случае, есть некоторая пища для размышлений, отличная от «репозиториев».требуется с EF ":)