Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在DDD中将实体添加到聚合根的正确方法_C#_Domain Driven Design - Fatal编程技术网

C# 在DDD中将实体添加到聚合根的正确方法

C# 在DDD中将实体添加到聚合根的正确方法,c#,domain-driven-design,C#,Domain Driven Design,我有一个名为Order的聚合根,我需要在订单中添加产品: public class Order { public void AddProduct(Product p) { } } 说到这一点,我想问一下DDD指南。我面临两个问题: Product有两个属性,除此之外:Product.OrderID和Product.Order。关于DDD,在调用Order.AddProduct之前,我应该设置哪些属性 或者我需要在Order.AddProduct内部设置这两个属性中的任何一个,类似于“p

我有一个名为
Order
的聚合根,我需要在
订单中添加
产品

public class Order {
  public void AddProduct(Product p) {
  }
}
说到这一点,我想问一下
DDD
指南。我面临两个问题:

  • Product
    有两个属性,除此之外:
    Product.OrderID
    Product.Order
    。关于
    DDD
    ,在调用
    Order.AddProduct
    之前,我应该设置哪些属性

  • 或者我需要在
    Order.AddProduct
    内部设置这两个属性中的任何一个,类似于“
    p.Order=this


  • 请注意,我正在使用
    订单
    产品
    作为示例。有人告诉我,这种关系可能不合适。谢谢。

    我建议使用工厂方法。这里有一个例子:

    public class Order {
        public Product addProduct(
            ProductId aProductId, 
            String aDescription 
        ) {
            Product product = new Product(
                this.orderId
                aProductId, 
                aDescription
            )
    
            //Publish event ProductWasAddedToOrder(this.orderId, aProductId) 
    
            return product;
        }
    } 
    
    然后,如果您愿意,您可以让订户(观察者模式)监听NewItemWasAddedToOrder事件,例如,它可以显示添加到购物车中的项目或类似的内容

    更新:我犯了一个大错误,因为我混淆了术语。当我在思考产品时,我想象的是一个订单项目,一个不存在的东西,它是在向订单添加新元素时创建的,我认为这是最好的方式

    想象一下,在您保存ProductId(对产品的引用)的订单中,另一方面,订购该产品的客户为此支付了20欧元。两个月后,系统管理员更改了同一产品的价格,由于您在订单中保存了对该产品的引用,如果您想检查客户当天支付的金额,您将获得新的价值。在订单中保存产品时,无论何时修改产品,都是在修改订单

    因此,我会在订单中添加一个新项目,其中包含产品当时拥有的特定信息。该项还应包含对产品的引用,以了解给定特定产品创建了多少项。下面是一个例子:

    public class Order {
        public OrderItem addItem(
            OrderItemId anItemId, 
            ProductId aProductId, 
            Price aPrice, 
            String aDescription 
        ) {
            OrderItem orderItem = new OrderItem(
                anItemId, 
                this.orderId,
                aProductId,
                aDescription, 
                aPrice
            )
    
            //Publish event NewItemWasAddedToOrder(this.orderId, anItemId) 
    
            return orderItem;
        }
    } 
    

    我建议使用工厂方法。这里有一个例子:

    public class Order {
        public Product addProduct(
            ProductId aProductId, 
            String aDescription 
        ) {
            Product product = new Product(
                this.orderId
                aProductId, 
                aDescription
            )
    
            //Publish event ProductWasAddedToOrder(this.orderId, aProductId) 
    
            return product;
        }
    } 
    
    然后,如果您愿意,您可以让订户(观察者模式)监听NewItemWasAddedToOrder事件,例如,它可以显示添加到购物车中的项目或类似的内容

    更新:我犯了一个大错误,因为我混淆了术语。当我在思考产品时,我想象的是一个订单项目,一个不存在的东西,它是在向订单添加新元素时创建的,我认为这是最好的方式

    想象一下,在您保存ProductId(对产品的引用)的订单中,另一方面,订购该产品的客户为此支付了20欧元。两个月后,系统管理员更改了同一产品的价格,由于您在订单中保存了对该产品的引用,如果您想检查客户当天支付的金额,您将获得新的价值。在订单中保存产品时,无论何时修改产品,都是在修改订单

    因此,我会在订单中添加一个新项目,其中包含产品当时拥有的特定信息。该项还应包含对产品的引用,以了解给定特定产品创建了多少项。下面是一个例子:

    public class Order {
        public OrderItem addItem(
            OrderItemId anItemId, 
            ProductId aProductId, 
            Price aPrice, 
            String aDescription 
        ) {
            OrderItem orderItem = new OrderItem(
                anItemId, 
                this.orderId,
                aProductId,
                aDescription, 
                aPrice
            )
    
            //Publish event NewItemWasAddedToOrder(this.orderId, anItemId) 
    
            return orderItem;
        }
    } 
    

    让聚合创建实体。这是客户端最简单的解决方案,因为“创建”和“添加产品”并没有分开

    public class Order 
    {
       private readonly List<Product> _products = new List<Product>();
    
       public Product CreateProduct(string name, Price price) 
       {
          var product = new Product(new ProductId(), name, price);
          _products.Add(product);
    
          return product;
       }
    }
    
    公共类秩序
    {
    私有只读列表_products=new List();
    公共产品CreateProduct(字符串名称、价格)
    {
    var product=新产品(新产品ID(),名称,价格);
    _产品。添加(产品);
    退货产品;
    }
    }
    
    请注意,
    CreateProduct
    的签名可能因您的需要而有所不同。例如,在某些情况下,您需要从客户处提供ID,而在其他情况下,订单会生成产品的ID


    注意:您可能应该具有Agragate Product和OrderItem或ProductOrderItem实体。OrderItem是将添加到订单的实体。编辑产品时,不会修改OrderItems。

    让聚合创建实体。这是客户端最简单的解决方案,因为“创建”和“添加产品”并没有分开

    public class Order 
    {
       private readonly List<Product> _products = new List<Product>();
    
       public Product CreateProduct(string name, Price price) 
       {
          var product = new Product(new ProductId(), name, price);
          _products.Add(product);
    
          return product;
       }
    }
    
    公共类秩序
    {
    私有只读列表_products=new List();
    公共产品CreateProduct(字符串名称、价格)
    {
    var product=新产品(新产品ID(),名称,价格);
    _产品。添加(产品);
    退货产品;
    }
    }
    
    请注意,
    CreateProduct
    的签名可能因您的需要而有所不同。例如,在某些情况下,您需要从客户处提供ID,而在其他情况下,订单会生成产品的ID


    注意:您可能应该具有Agragate Product和OrderItem或ProductOrderItem实体。OrderItem是将添加到订单的实体。编辑产品时,不会修改OrderItems。

    我认为您混淆了一些DDD术语。无法将聚合添加到聚合根。问题的标题是否应该是“在DDD中向聚合根添加实体的正确方式”?那会更有意义…我明白你的意思。。。非常感谢。我现在就换。我想你把DDD的一些术语弄糊涂了。无法将聚合添加到聚合根。问题的标题是否应该是“在DDD中向聚合根添加实体的正确方式”?那会更有意义…我明白你的意思。。。非常感谢。我现在要换衣服了,明白了。那么我应该按属性(即ProductName、ProductDescription等)而不是整个对象传递属性吗?我更新了答案,因为我一开始误解了这个问题。我明白了。那么我应该通过p吗