DDD解决方案结构

DDD solution structure

我正在尝试为新的 DDD 项目创建一个很好的解决方案结构。我创建了一个 "Core" 项目,我在其中添加了实体、ValueObjects 和存储库接口,然后我添加了一个 "Infrastructure" 项目,其中包含之前 IRepository 的实现。

现在,由于我的数据库将是 MongoDb,我需要在实体的某些字段中添加“[BsonDateTimeOptions]”等属性,这将需要添加对 MongoDb核心工程中的驱动包。

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

我能想到的是:

这种方法有一个问题,我将拥有实体模型的副本,它只有 MongoDb 属性,当向实体添加一些字段时,我将不得不修改模型太。这是正确的做法吗?

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

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

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

我这样做的方法是将聚合根、嵌套实体和值对象创建为普通对象(数据 + 行为,不依赖于 infrastructure/technology)。然后,当 persisting/rehydrating 时,我使用反射 store/load 来自存储库的聚合。存储库将任何已知的域对象映射到基础结构对象。例如,基本类型(string、bool、int、float、null)在没有任何转换的情况下存储。 Date is transformed to ISODate, the Guid is transformed to ObjectId等等。

这是可能的,因为反射并且很容易,因为 MongoDB 将对象存储为 JSON 并且几乎没有(或 none)阻抗不匹配。

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

这似乎总是 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; }