C# 如何引用聚合根';初始化子项时的属性/字段
假设我有两个域类Order和OrderItem,其中Order充当包含一个或多个Order项的聚合根。详情如下:C# 如何引用聚合根';初始化子项时的属性/字段,c#,C#,假设我有两个域类Order和OrderItem,其中Order充当包含一个或多个Order项的聚合根。详情如下: class OrderItem { public long LineItemId { get; set; } public String ProductId { get; set; } public DateTime CreatedDate { get; set; } } class Order
class OrderItem
{
public long LineItemId { get; set; }
public String ProductId { get; set; }
public DateTime CreatedDate { get; set; }
}
class Order
{
public long OrderId { get; set; }
public DateTime OrderDate { get; set; }
public String OrderStatus { get; set; }
public OrderItem[] OrderItems { get; set; }
public DateTime CreatedDate { get; set; }
}
现在,在初始化订单对象及其行项目时,是否可以在子项目初始值设定项中引用或访问聚合的根属性/字段,如下所示:
var order = new Order
{
OrderId = 1,
OrderDate = new DateTime(2012, 6, 1),
OrderStatus = "OPEN",
CreatedDate = DateTime.Now,
OrderItems = new[]
{
new OrderItem {
LineItemId = 1,
ProductId = "Orange",
CreatedDate = ??? // Initialize this to order's CreatedDate
},
new OrderItem {
LineItemId = 2,
ProductId = "Pear",
CreatedDate = ??? // Initialize this to order's CreatedDate
}
}
};
这里的目标是确保OrderItem具有与订单相同的时间戳(CreatedDate)——到T。如果(当然)不引入一个额外的变量来保存CreatedDate,那么这可以很容易地实现吗?您不能引用正在初始化的对象。出于一个简单的原因,它也允许您轻松创建一个循环 在您的例子中,您可以通过将订单的创建时间戳移动到构造函数中并将OrderItems属性更改为
public OrderItem[] OrderItems
{
get
{
return this.orderItems;
}
set
{
this.orderItems = value;
foreach (var item in this.orderItems)
{
item.CreatedDate = this.OrderDate;
}
}
}
并可能使OrderDate为只读。如果您必须有一个无参数构造函数,那么您也可以在OrderDate中实现foreach循环,并使用一个私有字段对其进行备份,这样所有内容都将同步
为完整起见,OrderDate在不使用构造函数时:
public DateTime OrderDate
{
get
{
return this.orderDate;
}
set
{
this.orderDate = value;
foreach (var item in this.orderItems)
{
item.CreatedDate = this.OrderDate;
}
}
}
另外,我非常确定我会将部分/大部分内容移动到构造函数中,尤其是时间戳是这方面的主要候选对象,与Id相同,因为这样可以使它们对于public
public OrderId是只读的[get;private set;}
。此外,我建议对OrderStatus使用枚举。您不能引用正在初始化的对象。出于一个简单的原因,它也允许您轻松创建循环
在您的例子中,您可以通过将订单的创建时间戳移动到构造函数中并将OrderItems属性更改为
public OrderItem[] OrderItems
{
get
{
return this.orderItems;
}
set
{
this.orderItems = value;
foreach (var item in this.orderItems)
{
item.CreatedDate = this.OrderDate;
}
}
}
如果你必须有一个无参数的构造函数,你也可以在OrderDate中实现foreach循环,并用一个私有字段来支持它,这样一切都会同步
为完整起见,OrderDate在不使用构造函数时:
public DateTime OrderDate
{
get
{
return this.orderDate;
}
set
{
this.orderDate = value;
foreach (var item in this.orderItems)
{
item.CreatedDate = this.OrderDate;
}
}
}
另外,我非常确定我会将部分/大部分内容移动到构造函数中,尤其是时间戳是这方面的主要候选对象,与Id相同,因为这样可以使它们对于public
public OrderId是只读的[get;private set;}
。此外,我建议对OrderStatus使用枚举。您不能在初始值设定项中引用父变量,但我认为以下内容可以以类似的方式完成您尝试执行的操作:
var order = new Order
{
OrderId = 1,
OrderDate = new DateTime(2012, 6, 1),
OrderStatus = "OPEN",
CreatedDate = DateTime.Now
};
order.OrderItems = new[]{
new OrderItem {
LineItemId = 1,
ProductId = "Orange",
CreatedDate = order.CreatedDate
},
new OrderItem {
LineItemId = 2,
ProductId = "Pear",
CreatedDate = order.CreatedDate
}};
您不能在初始值设定项中引用父变量,但我认为以下内容以类似的方式完成了您尝试执行的操作:
var order = new Order
{
OrderId = 1,
OrderDate = new DateTime(2012, 6, 1),
OrderStatus = "OPEN",
CreatedDate = DateTime.Now
};
order.OrderItems = new[]{
new OrderItem {
LineItemId = 1,
ProductId = "Orange",
CreatedDate = order.CreatedDate
},
new OrderItem {
LineItemId = 2,
ProductId = "Pear",
CreatedDate = order.CreatedDate
}};
嗯…这会让我远离对象初始值设定项…关于创建循环的可能性-如果编码员知道他在做什么,你就不能引用你正在初始化的对象。这是事实吗?@JohnGathogo为什么你这么专注于不使用构造函数?还有,如果你真的不能使用构造函数,并且必须将所有东西都集中在一个构造函数中go-更改OrderDate的实现以更改orderItems的CreatedDatetoo@JohnGathogo是的,是的,它是-看到其他人说同样的事情,我不专注于不使用构造函数。相信我,我使用构造函数-很多。我知道至少有几个替代方案来实现我的尝试。我只是喜欢尝试替代ives提供了一些方法来完成任务并使用在特定场景中表现良好的内容嗯…这会让我远离对象初始值设定项…关于创建循环的可能性-如果编码者知道他在做什么,你就不能引用你正在初始化的对象。这是事实吗?@JohnGathogo为什么你这么专注于不使用constructor?另外,如果您真的不能使用一个,并且必须一次性完成所有工作,那么请更改OrderDate的实现以更改orderItems的CreatedDatetoo@JohnGathogo是的,是的,它是-看到其他人说同样的事情,我不专注于不使用构造函数。相信我,我使用构造函数-很多。我至少知道我只是喜欢尝试其他的方法来完成一些事情,并在特定的场景中使用好的方法