Обобщённый репозиторий: за и против
Вопрос
Нужен ли в проекте на EF Core обобщённый IRepository<T>? Как бы вы его спроектировали?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Ограничения where T : class, IEntity для доступа к Id
DbSet<T> и DbContext уже реализуют репозиторий и единицу работы
Обобщённый репозиторий часто прячет IQueryable или наоборот течёт им
Специфичные запросы лучше в доменных репозиториях или query-объектах
Плюс: единая точка для тестов, кеша, мягкого удаления
Что могут спросить следом
- Как сделать мягкое удаление без репозитория?
- Что вернёт метод репозитория: IQueryable или IReadOnlyList?
Разбор
Технически сделать просто: interface IRepository<T> where T : class, IEntity с методами GetById, Add, Remove, а реализация поверх DbSet<T>. Ограничение на IEntity даёт доступ к Id.
Но я спрошу, зачем он нужен. DbContext уже реализует паттерн единицы работы, а DbSet<T> это репозиторий. Обобщённая обёртка часто либо возвращает IQueryable, и тогда абстракция протекает, либо прячет его, и тогда для каждого нового запроса приходится добавлять метод или тянуть все записи в память.
Поэтому я предпочитаю специфичные репозитории под агрегаты, где методы названы по смыслу: GetActiveOrdersForCustomer. Сквозные вещи вроде мягкого удаления и мультиарендности решаю глобальными фильтрами запросов EF Core. Обобщённый репозиторий оправдан, если команда договорилась о нём ради единообразия и тестов, но тогда я возвращаю материализованные IReadOnlyList, а не IQueryable.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.