У меня есть простой репозиторий, который извлекает некоторые данные с помощью EF6. Я также использую структуру DI для инъекции зависимостей.Как украсить репозиторий только для чтения репозиторием аудита при использовании UnitOfWork?
namespace Domain
{
public interface IMyRespository
{
List<MyObject> FetchObjects();
}
}
namespace Data
{
public class MyRepository : IMyRepository
{
private readonly MyDbContext _context;
public MyRepository(MyDbContext context)
{
_context = context;
}
public List<MyObjects> FetchObjects()
{
return _context.MyObjects.ToList();
}
}
}
Новое требование утверждает, что мне нужно регистрировать каждый вызов FetchObjects() и его выходы. Я думал, что это прекрасный пример применения шаблона Decorator.
namespace Domain
{
public class MyRepositoryDecorator : IMyRepository
{
private readonly IMyRepository _inner;
private readonly ILogRepository _logRepository;
public MyRepositoryDecorator(IMyRepository inner, ILogRepository logRepository)
{
_inner = inner;
_logRepository = logRepository;
}
public List<MyObjects> FetchObjects()
{
var objects = _inner.FetchObjects();
var logObject = new LogObject(objects);
_logRepository.Insert(logObject);
_logRepository.Save();
return objects;
}
}
}
Теперь я ищу, чтобы использовать шаблон UnitOfWork, и я не уверен, как реализовать в этом случае.
Как я понимаю, какой-то компонент должен управлять UnitOfWork. Таким образом, в этом случае класс обслуживания будет делать некоторые вызовы и в конце вызова Save/Commit в классе UnitOfWork.
Однако, если интерфейс репозитория указывает на действие только для чтения, нет причин для того, чтобы класс обслуживания обернул вызов в модуле UnitOfWork и вызывается Save/Commit в конце. Это выглядело бы очень странно. Однако декоратор требует, чтобы это выполняло свою работу.
У меня, вероятно, отсутствует какая-то существенная конструкция. Любые идеи о том, как правильно подойти к этому сценарию?
Спасибо за ответ. Я не думаю, что репозиторий-декоратор обязательно должен знать о UoW. Я просто не уверен, что декоратор может сделать предположение, что он всегда завернут в UoW. Проблема заключается в том, что если вызывающая служба не настроит UoW (потому что с ее точки зрения это просто чтение данных), Commit никогда не вызывается, а изменения, сделанные декоратором, теряются. – batkuip
Репозиторий не знает ни о каком UoW и всегда выполняет свои внутренние коммиты в каждом методе в этом сценарии. Но если служба не передает UoW, транзакция по всем репозиториям будет отменена. Если служба не использует UoW и вызывает множественные действия в одном или нескольких репозиториях, существует вероятность того, что некоторые операции будут совершены, а некоторые не будут в случае, если они не пройдут между ними. Но именно поэтому нам нужен UoW в качестве шаблона. –
Также всегда хорошо следовать принципу CQS (сформулированном Б.Meyer ~ 20 лет назад), в котором говорится, что если ваш метод возвращает какое-либо состояние, то это Query, и этот метод не должен вносить никаких изменений. И если ваш метод вносит изменения, то это команда, и она не должна возвращать какое-либо состояние (должно возвращать пустоту практически). Если вы будете следовать этому простому принципу, тогда не будет никаких «с его точки зрения, это просто чтение», это будет ясно с самого начала: если вы делаете команды, то используйте UoW, если вы только делаете запросы, тогда не делайте этого. –