1

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

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

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

命令查询分离接受方法应该改变状态或返回结果。没有问题。

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

我在服务端应用命令查询分离,但不在控制器类中应用。因为用户可能想查看创建的产品结果。但是commandServiceCreate Controller Action 方法中工作并且不返回创建的产品。

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

4

2 回答 2

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

这样,即使不使用 CQRS,您也应该遵循 POST-REDIRECT-GET 规则。

已编辑:抱歉,没有注意到您正在构建 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);
    }
}
于 2015-06-22T08:30:54.513 回答
1

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

commandService.OnProductAdd += (args)=>{
  var id = args.Product.Id;
}
于 2015-06-22T10:22:35.033 回答