Dalla mia comprensione di CQRS è possibile creare un set di DTO che soddisfano i requisiti degli schermi dell'interfaccia utente o delle applicazioni che potrebbero aver bisogno di consumarli.
Laddove questo esista nel progetto è basato sui requisiti poiché dipenderebbe se si desidera esporre questi DTO tramite servizi Web. In questo caso non lo inserirò nel livello Web ma piuttosto nel livello Applicazione o in un livello Façade dedicato.
Quindi si dispone di un repository di sola lettura o di un livello di accesso ai dati che popola direttamente i DTO. Penso che il lato Query delle cose dovrebbe essere ottimizzato per le prestazioni di lettura, nel qual caso le query dirette/stored procedure sulle viste del database o sulle tabelle e SqlDataReaders farebbero il lavoro migliore qui. Ma sarebbe sicuramente la pena di astrarre questo accesso dietro un'interfaccia in modo da poter aggiungere un'implementazione memorizzata nella cache più avanti lungo la traccia.
Se si sta utilizzando un ORM e si desidera eseguire il mapping dalle entità dominio alle DTO, è possibile che si disponga di un QueryRepository generico che ha metodi che prendono un ISpecification o un costrutto simile per la definizione delle query e un oggetto DtoAssembler per la creazione Dtos dai tuoi oggetti Dominio. Quindi avere un'implementazione ha un oggetto di prima classe per ciascuna query che si intende eseguire.
Ecco un esempio abbastanza elaborato ma spero che ti dia un'idea.
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;
}
}
Ho appena trovato un post sul blog di Jak Charlton che descrive il motivo per cui ha deciso di non utilizzare DDD per l'interrogazione: "Il lato Query di CQS non richiede entità fortemente tipizzate, né richiede DTI fortemente tipizzati - dato che sono in gran parte dati ad-hoc che mantengono queste entità e DTO consumerebbero una quantità sproporzionata di tempo di sviluppo per qualcosa che un DataTable può gestire più che adeguatamente " http://devlicio.us/blogs/casey/archive/2009/ 06/22/we-are-not-doing-ddd-part-two-cqs.aspx – rohancragg