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吗