首页 > 解决方案 > .Net Core - 多个后端系统的存储库模式

问题描述

我正在创建一个具有多个层的 .Net Core API

客户.API

客户.业务

客户服务

客户库

此时此 API 必须调用 2 个数据库系统(两个系统都应进行相同的更新),并且在不久的将来其中一个系统将被停用。

  1. 动态数据库
  2. SQL 服务器

我创建了如下所示的存储库层,并想知道这是否是正确的方法。

创建一个抽象层并在 Customer.Libs 中有这样的类

MultiDbBaseRepository.cs

SQLServerBaseRepository.cs

MultiDbBaseRepository => 这个类将调用两个存储库类 SQLDatabaseRespository 和 DynamoDbRepository SQlServerBaseRepository => 这个类将调用 SQLDatabaseRespository。

此时在 Startup.cs 中添加对 MultiDbRepository 的依赖或根据一些设置驱动此实例化,以避免将来代码部署。

AddScoped<ICustomerBaseRespository, MultiDbBaseRepository >

因此,服务层使用 ICustomerBaseRespository,此时应用程序将调用 MultiDbBaseRepository,并且更改会更新为 SQL 和 Dynamodb,如果将来更改启动,则应用程序将调用必要的数据库。

如果我违反了设计模式,你能告诉我吗?

标签: c#.netdesign-patternsrepository-pattern

解决方案


此 API 目前必须调用 2 个数据库系统(两个系统都应进行相同的更新),并且在不久的将来其中一个系统将被停用。

这几乎正​​是我在视频Composite as Universal Abstraction中介绍的场景。简而言之,您可以在这个(以及许多其他)场景中使用复合设计模式。

我从一些类名中猜测存储库应该与客户打交道,所以也许这样的事情是有道理的:

public interface ICustomerRepository
{
    void Insert(Customer customer);
    void Update(Customer customer);
    // More members like this..?
}

您现在可以定义一个CompositeCustomerRepository这样的:

public class CompositeCustomerRepository : ICustomerRepository
{
    private readonly repositories;

    public CompositeCustomerRepository(params ICustomerRepository[] repositories)
    {
        this.repositories = repositories;
    }

    void Insert(Customer customer)
    {
        foreach (var repo in repositories)
            repo.Insert(customer);
    }

    void Update(Customer customer)
    {
        foreach (var repo in repositories)
            repo.Update(customer);
    }
}

您还必须ICustomerRepository在其他两个与相关的两个数据库系统对话的类中实现接口:

public class DynamoDBCustomerRepository : ICustomerRepository { /*...*/ }
public class SqlServerCustomerRepository : ICustomerRepository { /*...*/ }

现在从特定实现组成一个存储库:

ICustomerRepository repo = new CompositeCustomerRepository(sqlRepo, dynamoRepo);

所有客户端都应该与ICustomerRepository接口而不是具体类型对话。客户将不会意识到他们正在与一个复合体而不是单个数据库交谈。这将使以后退役其中一个变得微不足道。

正如我在视频中介绍的那样,如果您的存储库还需要从数据库中读取实体,则您必须决定要从哪个数据库返回数据。一种选择是选择您能找到的第一个非空结果。我还在我的视频以及我的文章Coalescing Composite as a monoid 中介绍了这一点。


推荐阅读