Ответ 1
Из моего понимания CQRS вы создадите набор DTO, которые отвечают требованиям экранов пользовательского интерфейса или приложений, которые могут их потреблять.
Если это существует в проекте, оно основано на требованиях, поскольку это будет зависеть, если вы собираетесь разоблачить эти DTO через веб-службы. В этом случае я бы не поместил его в веб-слой, а скорее в уровень приложения или выделенный слой "Фасад".
Тогда у вас будет только хранилище данных или только доступ к данным, который напрямую заполняет DTO. Я думаю, что часть запросов должна быть оптимизирована для производительности чтения, и в этом случае здесь будут работать прямые запросы/хранимые процедуры в представлениях или таблицах базы данных и SqlDataReaders. Но определенно стоило бы абстрагировать этот доступ за интерфейсом, чтобы впоследствии добавить кэшированную реализацию вниз по треку.
Если вы используете ORM и хотите сопоставить свои объекты домена с DTO, тогда у вас может быть общий QueryRepository, у которого есть методы, которые используют ISpecification или подобную конструкцию для определения ваших запросов, а затем объект DtoAssembler для создания Dtos из объектов домена. Затем реализация имеет объект первого класса для каждого из запросов, которые вы собираетесь выполнять.
Вот довольно надуманный пример, но я надеюсь, что это даст вам представление.
public interface ISpecification<T>
{
Expression<Func<T, bool>> Predicate { get; }
}
public class ActiveCustomersSpecification : ISpecification<Customer>
{
private Expression<Func<Customer, bool>> predicate;
public ActiveCustomersSpecification()
{
predicate = c => c.IsActive;
}
#region ISpecicfication<Customer> Members
public Expression<Func<Customer, bool>> Predicate
{
get { return predicate; }
}
#endregion
}
public interface IQueryRepository<T>
{
IQueryable<T> GetQuery(ISpecification<T> specification);
IEnumerable<T> FindAllBy(ISpecification<T> specification);
}
public class CustomerDtoAssembler
{
public CustomerDto AssembleFrom(Customer customer)
{
var customerDto = new CustomerDto
{
Id = customer.Id
};
return customerDto;
}
}