DDD解决方案结构

时间:2018-10-01 18:30:39

标签: c# mongodb repository domain-driven-design clean-architecture

我正在尝试为新的DDD项目创建一个不错的解决方案结构。我创建了一个“核心”项目,在其中添加了实体,ValueObjects和存储库接口,然后添加了一个“基础结构”项目,其中包含先前IRepository的实现。

现在,由于我的数据库将是MongoDb,所以我需要在Entities的某些字段中添加“ [BsonDateTimeOptions]”之类的属性,这将需要在核心项目中添加对MongoDb驱动程序包的引用。 / p>

由于核心项目不应包含对MongoDb的任何引用,因此应仅包含业务逻辑,并且应在其他任何项目(移动设备-Xamarin)中可重用,在这种情况下,最佳做法是什么?

我能想到的是:

  • 实体将不包含对MongoDb的任何引用
  • 在基础架构项目中为每个实体创建一个模型,该模型是相关实体的副本,但具有MongoDb属性。
  • 创建一个层(在存储库中?),该层能够使用模型在db中进行查询,然后将其转换为实体,然后返回Entity,将模型对象隐藏在存储库中。

这种方法有一个问题,我将拥有实体的副本,即模型,该副本仅具有MongoDb属性,并且在向实体中添加某些字段时,我也必须修改模型。这是正确的方法吗?

一切都从this解决方案结构开始。

3 个答案:

答案 0 :(得分:2)

不要在域类中使用属​​性,而是在基础结构层中编写配置代码。

例如,这似乎一直是MongoDB.NET的一个选项。

BsonClassMap.RegisterClassMap<MyClass>(cm => 
{
    cm.AutoMap();
    cm.MapMember(c => c.DateOfBirth).SetSerializer(new DateTimeSerializer(dateOnly: true));
}

代替

[BsonDateTimeOptions(DateOnly = true)]
public DateTime DateOfBirth { get; set; }

答案 1 :(得分:1)

注意:我不使用C#,但这在PHP中有效,也许对您有帮助

我这样做的方法是将聚合根,嵌套实体和Value对象创建为普通对象(数据+行为,不依赖于基础架构/技术)。然后,在持久/补水时,我使用反射从存储库中存储/加载聚合。存储库正在将任何已知的域对象映射到基础结构对象。例如,原始类型(字符串,布尔值,整数,浮点数,空值)无需任何转换即可存储。将Date转换为ISODate,将Guid转换为ObjectId,依此类推。

由于反射和实现是很容易的,因为MongoDB将对象存储为JSON,并且阻抗不匹配很小(或没有)。

答案 2 :(得分:0)

是的,您描述的方法是正确的,但是您在存储库中称为层的只是基础结构层中的适配器。适配器使用mongodb技术实现repo接口,并使用映射器在两个模型之间进行转换。映射器也属于基础结构层。