DDD 在 2 个不同的数据库上持久聚合

DDD persisting aggregate on 2 different databases

我有一个通用 IRepository<T>,它在 Infrastructure.NHibernate 下实现,使用 Simple Injector 将实现注入接口。 IRepository<T> 住在我的 Domain 中,这样域对象就可以使用注入的存储库。

我有一个 User``AggregateRoot,它包含应用程序数据库中有关用户的一些详细信息,IdFirstnameLastname。我知道不关心持久性,但在这个阶段我们正在讨论这些对象是如何持久化的。

在我的 Web.UI(ASP.Net MVC 5) 中,我有一个可以更新用户详细信息的屏幕,FirstnameLastnameEmail , Address。 ID已存储但无法更新。

当我更新 User 详细信息时,我使用 IRepository<User> 更新 FirstnameLastname

问题:我也需要更新我们 OpenLdap 服务器中的 FirstnameLastnameEmailAddress

我有一个 Infrastructure.Ldap 项目,其中包含所有 Ldap 实现等。 (存储库、服务、实体、助手、转换器)。

更新 LDap 服务器的最佳方法是什么?

我是否在 Infrastructure.Ldap 实现的 Domain 中创建另一个 ISomeRepository 接口?这意味着我需要向 User 添加额外的属性,并且只覆盖 ORM 映射以忽略额外的属性。然后我使用 IRepository,接着使用 ISomeRepository 来更新两个数据库中的用户。

Web.UI 已经是一个基础设施问题,所以我只引用 Infrastructure.Ldap 项目并直接与 ldap 存储库对话,它将使用 LDapUser 对象。这将让我单独更新 Ldap 上的用户。

我很困惑,业务规则是我们需要更新用户详细信息。我假设从 DDD 的角度来看,所有需要更新的细节都需要存在于域中。我如何将此 User 保存在 2 个不同的数据存储中?

我上面的选项之一是否有效并通过了良好实践,或者是否有不同的解决方案?业务需要有 2 个不同的数据存储,因此我需要完成这项工作。

IdFirstnameLastname - 这存储在应用程序数据库中以防 Ldap 出现故障,并将在以后用于审计目的。

IdFirstnameLastnameEmailAddress - 这存储在用户管理的 OpenLdap 服务器部分.

有人能给我指出正确的方向吗?由于需要持久化的地方受到限制,因此很难严格地从 DDD 的角度来考虑这种情况。如果都在应用程序数据库上,那就很容易了。

您可以在存储库中使用 Composite 设计模式:

public IRepository<T>
{
    void Save(T entity);
}

public class CompositeRepository<T> : IRepository<T>
{
    private readonly IEnumerable<IRepository<T>> repositories;

    public CompositeRepository(IEnumerable<IRepository<T>> repositories)
    {
        if(repositories == null)
        {
            throw new ArgumentNullException("repositories");
        }
        this.repository = repositories;
    }

    public void Save(T entity)
    {
        foreach(var repository in repositories)
        {
            repository.Save(entity);
        }
    }
}

让我们假设存在 SqlUserRepositoryLdapUserRepository 并且都实现了 IRepository<User>。然后你可以使用容器注册CompositeUserRepository

container.RegisterCollection<IRepository<User>>(new[] { typeof(SqlUserRepository), 
                                                         typeof(LdapUserRepository) });
container.Register<IRepository<User>, CompositeRepository<User>>();

感谢您的服务进一步使用 IRepository<User>,并且当您将持久性 User 添加到 LDAP 时,它们不必更改。我们还通过这种方式解决了这个问题 - Single Responsibility 存储库上下文中的原则。