Исходя из моего понимания CQRS, вы могли бы создать набор DTO, которые отвечают требованиям экранов пользовательского интерфейса или приложений, которые могут потребоваться для их использования.
То, где это существует в проекте, основано на требованиях, поскольку это будет зависеть от того, собираетесь ли вы показывать эти DTO через веб-сервисы.
В этом случае я бы поместил его не на веб-уровне, а на прикладном уровне или выделенном фасадном уровне.
Тогда у вас будет хранилище только для чтения или слой доступа к данным, который напрямую заполняет DTO. Я думаю, что сторона запросов должна быть оптимизирована для производительности чтения, и в этом случае прямые запросы / хранимые процедуры для представлений или таблиц базы данных и SqlDataReaders подойдут лучше всего. Но, безусловно, стоило бы абстрагировать этот доступ за интерфейсом, чтобы позже можно было добавить кешированную реализацию.
Если вы используете ORM и хотите сопоставить свои доменные сущности с DTO, то у вас может быть общий QueryRepository, у которого есть методы, которые принимают спецификацию IS или аналогичную конструкцию для определения ваших запросов, тогда объект 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;
}
}