... не имеет ли смысла никогда не иметь метод добавления / сохранения на
хранилище при использовании шаблона UoW и имеет только эту функциональность
на интерфейсе IUnitOfWork?
Да, я думаю, что имеет смысл иметь метод Save только в интерфейсе IUnitOfWork. Однако я больше не использую шаблон хранилища с EF. Вместо этого я теперь использую эти варианты шаблонов команд и запросов.
Если вы подумаете об этом, EF DbContext действительно выполняет 3 вещи: 1.) он функционирует как ваш репозиторий для чтения состояния сущности, 2.) как ваш репозиторий для изменяющегося состояния сущности, и 3.) как UnitOfWork для отслеживание нескольких изменений и объединение их в одну транзакцию для сохранения мутаций состояния.
Итак, почему бы не разделить эти 3 обязанности на 3 различных интерфейса?
public interface IUnitOfWork
{
int SaveChanges();
}
public interface ICommandEntities : IQueryEntities
{
void Create(Entity entity);
void Update(Entity entity);
void Purge(Entity entity);
}
public interface IQueryEntities
{
IQueryable<AggregateRoot1> AggregateRoot1s { get; }
IQueryable<AggregateRoot2> AggregateRoot2s { get; }
IQUeryable<AggregateRootN> AggregateRootNs { get; }
IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query,
Expression<Func<TEntity, object>> expression)
where TEntity : Entity;
}
Затем вы можете реализовать эти 3 интерфейса в своем классе DbContext. Это сохраняет интерфейсы красивыми и разделенными, и позволяет зависимостям внедрять только те методы DbContext, которые вам нужны.
Например, ваш домен должен быть невежественным, верно? В этом случае не передавайте какие-либо зависимости классов вашего домена в интерфейс IUnitOfWork. Вместо этого обработайте IUnitOfWork в корне композиции IoC (или в фильтре действий MVC). Затем ваши обработчики запросов и команд работают только с интерфейсами ICommandEntities и IQueryEntities.