0

我在项目中有一个Customer业务实体Domain,我想DomainService根据它的属性在项目中实例化它。有些业务逻辑在创建时需要强制执行,例如Salary依赖FirstName(仅示例)。我不希望它的设置器公开而失去封装。

如何在不丢失封装的情况下实例化/初始化它。设置器的私有可以更改,而不是公开的。

 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
    }
4

3 回答 3

3

如果您的要求是严格的封装..那么您唯一真正的选择(我现在能想到的)是使用构造函数:

public Customer(string firstName, string surname, decimal salary, ...)

允许像这样直接操作域对象并不是一种罪过。如果您担心可能会发生什么......要么给他们支持字段,要么让您的实体公开一个公共接口以对其进行更改(这可能会使用某种Guard类来确定有效性)。

于 2013-07-12T03:36:29.403 回答
1

通常,您将在两种情况下创建 Customer 实例。

答:从Repository检索现有客户在这种情况下,考虑到在将Customer存储到Repository之前已验证约束时,您无需强制执行约束。

B:一个全新的客户。如果有一些重要的域约束,您可以使用工厂来封装创建。

于 2013-07-12T04:38:53.160 回答
0

如果您的验证可以在该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;
    }
}
于 2013-07-12T06:07:35.750 回答