>域不能知道持久层,换句话说,域与EF完全分离.但是,为了将数据保存到数据库,每个实体必须附加到EF上下文或添加到EF上下文中.我知道你应该使用工厂来创建聚合根的实例,所以工厂可以用EF上下文注册创建的实体.这似乎违反DDD规则,因为工厂是域的一部分,而不是持久层的一部分.我应该如何创建和注册实体,以便在需要时正确地保留到数据库?
一个聚合实体应该是创建它的子实体吗?我的意思是,如果我有一个组织,该组织有员工实体的集合,Organization应该有一个方法,如CreateEmployee或AddEmployee?如果创建员工实体不在哪里记住,组织聚合根“拥有”每个员工实体.
>首先使用EF代码时,每个实体的ID(以数据库中的标识列的形式)自动处理,通常不会被用户代码更改.由于DDD表示域与持久性无知分开,似乎暴露ID在域中是一件奇怪的事情,因为这意味着域应该处理向新创建的实体分配唯一的ID.我应该关心暴露实体的ID属性吗?
我意识到这些是开放式的设计问题,但是我尽量在使用EF作为持久层的同时,坚持使用DDD设计模式.
提前致谢!
// This is what gets persisted public class TrainStationState { public Guid Id { get; set; } public string FullName { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } // ... more state here } // This is what you work with public class TrainStation : IExpose<TrainStationState> { TrainStationState _state; public TrainStation(TrainStationState state) { _state = state; //You can also copy into member variables //the state that's required to make this //object work (think memento pattern). //Alternatively you could have a parameter-less //constructor and an explicit method //to restore/install state. } TrainStationState IExpose.GetState() { return _state; //Again,nothing stopping you from //assembling this "state object" //manually. } public void IncludeInRoute(TrainRoute route) { route.AddStation(_state.Id,_state.Latitude,_state.Longitude); } }
现在,关于总体生命周期,主要有两种情况:
>创建新聚合:您可以使用工厂,工厂方法,构建器,构造函数,…适合您的需要.当您需要持久化聚合时,查询其状态并持久化(通常此代码不在您的域中,并且非常通用).
检索一个现有的聚合:可以使用一个存储库,一个dao,…适合你的需要.重要的是要明白,从永久存储中检索的是一个状态POCO,您需要注入原始聚合(或使用它来填充其私有成员).这一切都发生在仓库/ DAO门面后面.不要用这种通用行为来混淆你的呼叫站点.
2:有几件事情想到了.这里有一个列表:
>聚合根是一致性边界.你在组织和员工之间看到什么一致性要求?
>组织机构COULD作为员工工厂,不变更组织状态.
>“所有权”不是什么聚合.
>聚合根通常具有在聚合中创建实体的方法.这是有道理的,因为根要负责在聚合体内实施一致性.
3:从外面分配标识符,覆盖,继续.这并不意味着暴露他们(只有在POCO州).