如何确保DDD中域模型的完整性

时间:2014-07-09 14:37:59

标签: asp.net-mvc domain-driven-design ddd-repositories

我有一个名为country的域名,其结构如下

 public class Country : Entity
    {
        public Country()
        {
            States=new List<State>();
        }
        public string CountryName { get; set; }
        public string CountyCode { get; set; }

        public virtual ICollection<State> States { get; private set; }

        public void AddNewState(State state)
        {
            if(IsDuplicateStateExists(state.GetHashCode())) throw new ApplicationOperationException(Messages.Validation_DuplicateState){HttpCode = 409};

            States.Add(state);
        }

        bool IsDuplicateStateExists(int hashCode)
        {
           return States.Any(x => x.GetHashCode() == hashCode);
        }

        public State GetStateById(int stateId)
        {
            return States.FirstOrDefault(x => x.Id == stateId);
        }

        public void DeleteState(int stateId)
        {
            var state = GetStateById(stateId); 
            if(state==null) return;
            state.CountryId = 0; // This is for informing EF to delete this object Check Orphan entities in EF
            States.Remove(state);
        }

        public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List<ValidationResult>();

            if (CountryName.Length < 3) results.Add(new ValidationResult(Messages.Validation_CountryNameRequired,new String[]{"CountryName"}));
            if (CountyCode.Length < 2) results.Add(new ValidationResult(Messages.Validation_CountryCodeRequired, new String[] { "CountyCode" }));
            return results;
        }
    }

在这里,我对这个实体的设计几乎没有疑问, 1.)实体可以抛出错误吗?

2。)将验证(而非业务规则)逻辑放入enity

是否是个好主意

3。)&#34;国家有州,每个州必须有县&#34;, 如果这是设计规范中的一条规则,Addnewstate(),IsDuplicateStatesExists(),RemoveStates()有资格保留在国家实体内,或者我应该转移到应用程序服务

2 个答案:

答案 0 :(得分:1)

1。)实体可以抛出错误吗?

是的,当然。您可以在违反业务规则时抛出异常。

2。)将验证(而非业务规则)逻辑放入enity

是否是个好主意

我更愿意在实体中加入业务验证。所以我不会在实体中验证像字符串长度这样的逻辑。上层应该验证非业务逻辑。但我认为在实体中使用[Required][StringLength]等数据注释是个好主意,因为它们非常简单,让我们的生活更轻松:P

3。)“国家有州,每个州必须有县”,如果这是设计规范中的一条规则,Addnewstate(),IsDuplicateStatesExists(),RemoveStates()有资格保留在国家实体内,或者我应该转移到应用服务。

保留在Country实体内。但是你的实现是不正确的。 两个不同的实体可以生成相同的哈希码!如果您正确实施了StatesISet<T>,则可以将GetHashCode属性设置为Equals} State类的方法。但我更愿意根据州名来检查重复。

答案 1 :(得分:0)

实体只是数据传输对象。它们告诉实体框架数据库表应该是什么样子,并为实体框架提供一个位置来转储它从该表中选择的数据。因此,它们应该只具有与数据库相关的业务逻辑。例如,如果字符串列不可为空,则可以将[Required]属性添加到您的属性中。超出它的任何东西都属于其他地方

“其他地方”可能是您的存储库,服务或视图模型。它的业务逻辑与如何检索实体有关,例如,您将其放入存储库或服务中。如果它的业务逻辑与用户应如何在表单中输入数据相关,那么它属于视图模型。