Прежде всего, если ваш Repository<T>
не имеет какой-либо общей функциональности (у вас есть только абстрактные методы и нет реализации), первое, что я хотел бы сделать, это избавиться от него.Лучше всего, чтобы все другие части вашей программы обращались к хранилищу только через интерфейс IRepository<T>
, что позже предоставит вам большую свободу.
Во-вторых, наличие класса EFRepository
означает, что вы хотите выйтивозможность переключиться на другой ORM один день.Мое мнение - не делай этого.Если вы выбрали EF, придерживайтесь EF.Если вы действительно думаете, что это вариант, хотя бы создайте отдельную сборку с пространством имен MyApp.EntityORM
или любым другим, поместите туда все свои классы репозитория и избавьтесь от префикса EF
.Затем, если это когда-нибудь случится, возможно, вы когда-нибудь сможете загрузить нужный ORM с помощью внедрения зависимостей, не меняя остальной код.
Из моего опыта: между ORM могут быть тонкие различия, которые мешают вамот их взаимозаменяемости по-настоящему прозрачным способом, и есть небольшой шанс, что вам когда-нибудь понадобится изменить свой ORM для одного проекта.
Во-вторых, я также предпочитаю оборачивать базовую функциональность базового репозитория в другом классе.(образец декоратора, как уже сказал Дэн Брайант), в отличие от переопределения уже существующего класса.Причина в том, что переопределение часто приводит к необходимости иметь дело с внутренними компонентами базового класса, и это может иногда становиться немного запутанным.
Из вашего вопроса не совсем ясно, как должен вести себя «контролируемый репозиторий», но если это просто IRepository<T>
(он проверяет все методы, реализованные в IRepository<T>
), то вам не нужен отдельный интерфейс:
interface IRepository<T>
class Repository<T> : IRepository<T>
class AuditableRepository<T> : IRepository<T>
Добавляя к тому, что сказал Дэн, выможет иметь фабричный метод, который создаст соответствующую оболочку:
class AuditableRepository<T> : IRepository<T>
{
public static IRepository<T> CreateFrom(IRepository<T> baseRepo)
{
// wrap base repo in an auditable repository
// and return it
return new AuditableRepository<T>(baseRepo);
}
}