Laz*_*Laz 16 domain-driven-design cqrs
我已经使用域模型和存储库实现了DDD的命令端,但是如何实现查询端呢?
我是否为UI创建了一个全新的域模型,它在项目结构中保存在哪里......在域层,UI层等中?
此外,我使用什么作为我的查询机制,我是否专门为UI域对象创建新的存储库,而不是存储库或其他东西?
小智 6
根据我对CQRS的理解,您将创建一组DTO,以满足可能需要使用它们的用户界面屏幕或应用程序的要求.
如果您要通过Web服务公开这些DTO,那么项目中存在的内容基于要求.在这种情况下,我不会将它放在Web层中,而是放在Application层或专用的Façade层中.
然后,您将拥有一个只读存储库或数据访问层,它直接填充DTO.我认为事情的查询方面应该针对读取性能进行优化,在这种情况下,数据库视图或表和SqlDataReaders上的直接查询/存储过程将在这里做得最好.但是在界面背后提取这种访问权限肯定是值得的,因此您可以在以后的轨道中添加缓存实现.
如果您正在使用ORM并希望从您的域实体映射到DTO,那么您可以拥有一个通用的QueryRepository,其中包含用于定义查询的ISpecification或类似构造的方法,然后是用于从您的域创建Dtos的DtoAssembler对象对象.然后让实现为您要执行的每个查询都有一个第一类对象.
这是一个相当人为的例子,但我希望它能给你一个想法.
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;
}
}
Run Code Online (Sandbox Code Playgroud)