C# 在不丢失封装的情况下实例化业务实体
我在C# 在不丢失封装的情况下实例化业务实体,c#,design-patterns,domain-driven-design,C#,Design Patterns,Domain Driven Design,我在域项目中有一个客户业务实体,我想根据其属性在域服务项目中实例化它。有一些业务逻辑在创建时需要强制执行,例如,Salary依赖于FirstName(仅示例)。我不希望它的setter是公共的,这会丢失封装 如何在不丢失封装的情况下实例化/初始化它。setter的private可以更改,而不是public public class Customer { public int Id { get; private set; } public string
域
项目中有一个客户
业务实体,我想根据其属性在域服务
项目中实例化它。有一些业务逻辑在创建时需要强制执行,例如,Salary
依赖于FirstName
(仅示例)。我不希望它的setter是公共的,这会丢失封装
如何在不丢失封装的情况下实例化/初始化它。setter的private可以更改,而不是public
public class Customer
{
public int Id { get; private set; }
public string Firstname { get; private set; }
public string Surname { get; private set; }
public decimal Salary { get; private set; }
//... other properties
}
如果您对封装有如此严格的要求。。那么您唯一的实际选择(我现在可以想到)就是使用构造函数:
public Customer(string firstName, string surname, decimal salary, ...)
允许像这样直接操纵域对象不是一种罪恶。如果你那么担心会发生什么。。要么给它们提供支持字段,要么让您的实体公开一个公共接口来对其进行更改(这可能会使用某种
保护类来确定有效性)。如果您的要求对封装非常严格。。那么您唯一的实际选择(我现在可以想到)就是使用构造函数:
public Customer(string firstName, string surname, decimal salary, ...)
允许像这样直接操纵域对象不是一种罪恶。如果你那么担心会发生什么。。要么给他们提供支持字段,要么让您的实体公开一个公共接口,以便对其进行更改(这可能会使用某种保护类来确定有效性)。通常,您将创建一个客户实例
答:从存储库检索现有的客户。在这种情况下,考虑到在客户存储到存储库之前已对约束进行了验证,您不需要强制执行约束
B:一个全新的客户。如果存在一些重要的域约束,您可以使用工厂来封装创建。通常,有两种情况下您将创建一个客户实例
答:从存储库检索现有的客户。在这种情况下,考虑到在客户存储到存储库之前已对约束进行了验证,您不需要强制执行约束
B:一个全新的客户。如果存在一些重要的域约束,您可以使用工厂来封装创建。如果您的验证可以在Customer
级别工作,建议添加一个属性,例如IsValid
,该属性在Customer
对象上运行业务规则。两种实现可以如下所示:
public bool IsValid
{
get
{
return !string.IsNullOrWhiteSpace(Firstname) && Salary > 0;
}
}
public Dictionary<string, string> IsValid2
{
get
{
var errors = new Dictionary<string, string>(); //TODO: Instantiate only if errors are found
if (string.IsNullOrWhiteSpace(Firstname))
{
errors.Add("ERR_001", "First name is invalid.");
}
if (Salary <= 0)
{
errors.Add("ERR_002", "Salary should be a positive number.");
}
return errors;
}
}
public bool有效
{
得到
{
return!string.IsNullOrWhiteSpace(Firstname)&&Salary>0;
}
}
公共词典有效2
{
得到
{
var errors=new Dictionary();//TODO:仅在发现错误时实例化
if(string.IsNullOrWhiteSpace(Firstname))
{
错误。添加(“ERR_001”,“名字无效”);
}
if(Salary如果您的验证可以在Customer
级别工作,建议添加一个属性,例如IsValid
,该属性在Customer
对象上运行业务规则。两个实现可能如下:
public bool IsValid
{
get
{
return !string.IsNullOrWhiteSpace(Firstname) && Salary > 0;
}
}
public Dictionary<string, string> IsValid2
{
get
{
var errors = new Dictionary<string, string>(); //TODO: Instantiate only if errors are found
if (string.IsNullOrWhiteSpace(Firstname))
{
errors.Add("ERR_001", "First name is invalid.");
}
if (Salary <= 0)
{
errors.Add("ERR_002", "Salary should be a positive number.");
}
return errors;
}
}
public bool有效
{
得到
{
return!string.IsNullOrWhiteSpace(Firstname)&&Salary>0;
}
}
公共词典有效2
{
得到
{
var errors=new Dictionary();//TODO:仅在发现错误时实例化
if(string.IsNullOrWhiteSpace(Firstname))
{
错误。添加(“ERR_001”,“名字无效”);
}
如果(你可能会发现这篇关于设计实体的博文很有趣:你可能会发现这篇关于设计实体的博文很有趣:ctor是保护不变量的最佳位置。我包装了DateTime。现在,我需要使用DateTimeWrapper在客户实体内验证DateOfBirth,但我不能使用依赖项注入,因为构造tor与上面类似。有什么想法吗?tor是保护不变量的最佳位置。我包装了DateTime。现在,我需要使用DateTimeWrapper在客户实体内验证DateOfBirth,但我不能使用依赖项注入,因为构造函数与上面类似。有什么想法吗?