jnm*_*nm2 5 c# domain-driven-design
我刚刚开始了解 DDD。贫乏的领域模型(据我所知实际上只不过是持久性模型)并将逻辑推入视图模型并不能解决问题。因此,我对更复杂的环境之一进行了建模(饲料营养/价格优化器)。我完全同意 DDD 实体具有私有设置器并公开只读集合的事实,并且改变它们的唯一方法是调用实体上的方法。非常容易测试,很难误用。
这是我的问题。将这个东西保存到数据库中很简单。对我来说不明显的是如何在不破坏封装的情况下再次实现它。
我一直在使用实体框架来加载数据模型。我知道它能够使用域实体的私有设置器,但是:1)反射的魔力可能会误导推理。2) 我绝对不想尝试跳过数据模型并强制域模型尝试与 EF 良好配合。3)数据库的规范化程度略低于领域模型。4) 我认为 EF 与IReadOnlyList<>.
我还尝试重建和重播方法调用,这将导致实体处于等效状态,但这似乎是不必要的复杂性。我不清楚代码是否正确。而且这种方法会引发大量的线性规划求解和滞后。
为了保持域实体的干净,我能想到的最后一个手段是在每个被调用的实体上使用内部静态工厂方法,该方法Materialize接收字段作为参数并返回实体的新实例。存储库应该是唯一访问它的东西。这是一个好的解决方案吗?我还应该考虑什么?
编辑:我没有具体化保存的状态,而是让我的存储库模拟事件源(重播方法)。我喜欢这个方向。该数据库还不是事件源,但可以随时轻松切换,因为存储库隐藏了这一点。
基本上你想使用 Memento 模式,它坚固但无聊,并且维护成本很高。很高兴您已经意识到直接使用 EF 实体(无论它们如何 POCO)是一个问题,但是有一个简单的解决方案。
严格将 EF POCO 视为从数据库读取/写入的 DTO。如果您正确使用存储库模式,则可以将聚合根映射(手动或使用自动映射器)到存储库内的EF POCO 。
应用程序的其余部分不会了解有关 EF 的任何信息,只有您的存储库将充当从域对象到一个或多个 EF POCO 并返回的“转换器”。为了将数据放入域对象中,您可以定义“只读”属性,例如
List<string> _data=new List<string>();
public IEnumerable<string> Data
{
get{ return _data;}
private set{
_data=value.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
这将允许像自动映射器这样的工具来填充对象状态。请注意,该对象仍然是封装的,但私有设置器也充当数据“导入器”。
就我个人而言,我正在使用这种方法,但没有使用 EF,因为我更喜欢 json 对象并按原样存储它。Ofc,该表具有查询所需的列,但有一Data列保存可以轻松恢复的对象状态。只要你的聚合设计得当,它就能完美地工作。
| 归档时间: |
|
| 查看次数: |
2331 次 |
| 最近记录: |