应用命令查询分离(CQS)时如何返回结果

时间:2015-06-22 08:14:23

标签: c# design-patterns command-query-separation

我在服务端分离我的查询和命令,如下所示:

public class ProductCommandService{
    void AddProduct(Product product);
}

public interface ProductQueryService{
    Product GetProduct(Guid id);
    Product[] GetAllProducts();
}

Command Query Separation接受方法应该更改状态或返回结果。没问题。

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();
    }
}

我在服务端应用命令查询分离但不在控制器类中应用。因为用户可能想要查看创建的产品结果。但 commandService 适用于创建控制器操作metod,并且不会返回已创建的产品。

我们将返回给用户什么?所有产品? CQS是否适用于应用程序生命周期?

2 个答案:

答案 0 :(得分:1)

在这种情况下,我通常会在客户端上生成新的实体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你也应该这样做。

EDITED: 抱歉,没有注意到您正在构建API,而不是MVC应用程序。 在这种情况下,我会返回一个新创建的产品的URL:

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);
    }
}

答案 1 :(得分:1)

命令方法不返回任何内容,只更改状态,但命令事件可以返回您需要的参数。

commandService.OnProductAdd += (args)=>{
  var id = args.Product.Id;
}