Всем привет,
Поиском по форуму ответа не нашел, в Интернетах предлагают самые различные варианты решений, к сожалению, без анализа плюсов/минусов. Поэтому обращаюсь за советом к сообществу.
Итак, чего хочется:
Абстрагировать Entity Framework от всего остального кода в виде интерфейсов Repository / Unit of Work (в далеком будущем не исключен вариант замены связки EF + SQL Server на, например, NoSQL хранилище, поэтому очень не хочется завязывать остальной код на специфичные для EF интерфейсы)
Полная изоляция бизнес-логики в целях юнит-тестирования (т.е. создаем mock'и для IRepository / IUnitOfWork)
Репозиторий не должен знать ничего о бизнес-логике (кол-во сущностей, специфические запросы для определенной сущности и т.п.), т.е. должен быть полностью обобщённым (generic)
Собственно, последний пункт вызывает больше всего вопросов, так как большинство примеров, которые я находил в Интернете, предлагают примерно такие варианты:
interface IUnitOfWork
{
IRepository<Customer> Customers { get; }
IRepository<Order> Orders { get; }
// и т.п.
void Commit();
}
а то и
interface IUnitOfWork
{
ICustomerRepository Customers { get; }
IOrderRepository Orders { get; }
// и т.п.
void Commit();
}
Которые плохи "протеканием" знаний о бизнес-сущностях в слой инфраструктуры. А вариант наподобие такого
interface IUnitOfWork
{
IRepository<T> Repository { get; }
void Commit();
}
встречается очень редко. А если и встречается, то в подобной реализации IUnitOfWork ручками кэшируются ссылки на DbSet<T> (хотя, вроде бы, DbContext сам должен это делать?
)
Кроме этого, в примерах по Code First довольно часто создается класс-наследник DbContext, который, опять-таки, обладает знаниями о бизнес-логике:
public class MyDbContext: DbContext
{
// ...
public DbSet<Customer> Customers { get; }
// ...
}
Это какое-то требование EF Code First — объявлять все возможные варианты параметризации DbSet как члены класса-наследника DbContext, или так делают просто для удобства, не задумываясь о low coupling и single responsibility principle ?
В общем, я немного запутался
— наставьте, пожалуйста, на путь истинный!
Спасибо!