应用命令查询分离 (CQS) 时如何 return 结果
How to return result while applying Command query separation (CQS)
我在服务端将查询和命令分开,如下所示:
public class ProductCommandService{
void AddProduct(Product product);
}
public interface ProductQueryService{
Product GetProduct(Guid id);
Product[] GetAllProducts();
}
Command Query Separation 接受方法应该改变状态或 return 结果。没问题。
public class ProductController: ApiController{
private interface ProductCommandService commandService;
private interface ProductQueryService queryService;
[HttpPost]
public ActionResult Create(Product product){
commandService.AddProduct(product);
return ???
}
[HttpGet]
public Product GetProduct(Guid id){
return commandService.GetProduct(id);
}
[HttpGet]
public Product[] GetAllProducts(){
return queryService.GetAllProducts();
}
}
我在服务端应用命令查询分离,但在控制器class中没有应用。因为用户可能希望看到创建的产品结果。但是 commandService 在 Create Controller Action 方法中工作,而不是 return 创建产品。
我们会return给用户什么?所有产品? CQS 是否适用于应用程序生命周期?
在这种情况下,我通常会在客户端生成新的实体 ID。
像这样:
public class ProductController: Controller{
private IProductCommandService commandService;
private IProductQueryService queryService;
private IIdGenerationService idGenerator;
[HttpPost]
public ActionResult Create(Product product){
var newProductId = idGenerator.NewId();
product.Id = newProductId;
commandService.AddProduct(product);
//TODO: add url parameter or TempData key to show "product created" message if needed
return RedirectToAction("GetProduct", new {id = newProductId});
}
[HttpGet]
public ActionResult GetProduct(Guid id){
return queryService.GetProduct(id);
}
}
这样您也遵循了 POST-REDIRECT-GET 规则,即使不使用 CQRS 也应该这样做。
已编辑:
抱歉,没有注意到您正在构建 API,而不是 MVC 应用程序。
在这种情况下,我将 return 一个 URL 到新创建的 Product:
public class ProductController: ApiController{
private IProductCommandService commandService;
private IProductQueryService queryService;
private IIdGenerationService idGenerator;
[HttpPost]
public ActionResult Create(Product product){
var newProductId = idGenerator.NewId();
product.Id = newProductId;
commandService.AddProduct(product);
return this.Url.Link("Default", new { Controller = "Product", Action = "GetProduct", id = newProductId });
}
[HttpGet]
public ActionResult GetProduct(Guid id){
return queryService.GetProduct(id);
}
}
命令方法不return任何东西,只改变状态但命令事件可以return你需要的参数。
commandService.OnProductAdd += (args)=>{
var id = args.Product.Id;
}
我在服务端将查询和命令分开,如下所示:
public class ProductCommandService{
void AddProduct(Product product);
}
public interface ProductQueryService{
Product GetProduct(Guid id);
Product[] GetAllProducts();
}
Command Query Separation 接受方法应该改变状态或 return 结果。没问题。
public class ProductController: ApiController{
private interface ProductCommandService commandService;
private interface ProductQueryService queryService;
[HttpPost]
public ActionResult Create(Product product){
commandService.AddProduct(product);
return ???
}
[HttpGet]
public Product GetProduct(Guid id){
return commandService.GetProduct(id);
}
[HttpGet]
public Product[] GetAllProducts(){
return queryService.GetAllProducts();
}
}
我在服务端应用命令查询分离,但在控制器class中没有应用。因为用户可能希望看到创建的产品结果。但是 commandService 在 Create Controller Action 方法中工作,而不是 return 创建产品。
我们会return给用户什么?所有产品? CQS 是否适用于应用程序生命周期?
在这种情况下,我通常会在客户端生成新的实体 ID。 像这样:
public class ProductController: Controller{
private IProductCommandService commandService;
private IProductQueryService queryService;
private IIdGenerationService idGenerator;
[HttpPost]
public ActionResult Create(Product product){
var newProductId = idGenerator.NewId();
product.Id = newProductId;
commandService.AddProduct(product);
//TODO: add url parameter or TempData key to show "product created" message if needed
return RedirectToAction("GetProduct", new {id = newProductId});
}
[HttpGet]
public ActionResult GetProduct(Guid id){
return queryService.GetProduct(id);
}
}
这样您也遵循了 POST-REDIRECT-GET 规则,即使不使用 CQRS 也应该这样做。
已编辑: 抱歉,没有注意到您正在构建 API,而不是 MVC 应用程序。 在这种情况下,我将 return 一个 URL 到新创建的 Product:
public class ProductController: ApiController{
private IProductCommandService commandService;
private IProductQueryService queryService;
private IIdGenerationService idGenerator;
[HttpPost]
public ActionResult Create(Product product){
var newProductId = idGenerator.NewId();
product.Id = newProductId;
commandService.AddProduct(product);
return this.Url.Link("Default", new { Controller = "Product", Action = "GetProduct", id = newProductId });
}
[HttpGet]
public ActionResult GetProduct(Guid id){
return queryService.GetProduct(id);
}
}
命令方法不return任何东西,只改变状态但命令事件可以return你需要的参数。
commandService.OnProductAdd += (args)=>{
var id = args.Product.Id;
}