c# - .Net Core - 多个后端系统的存储库模式
问题描述
我正在创建一个具有多个层的 .Net Core API
客户.API
客户.业务
客户服务
客户库
此时此 API 必须调用 2 个数据库系统(两个系统都应进行相同的更新),并且在不久的将来其中一个系统将被停用。
- 动态数据库
- SQL 服务器
我创建了如下所示的存储库层,并想知道这是否是正确的方法。
创建一个抽象层并在 Customer.Libs 中有这样的类
MultiDbBaseRepository.cs
SQLServerBaseRepository.cs
MultiDbBaseRepository => 这个类将调用两个存储库类 SQLDatabaseRespository 和 DynamoDbRepository SQlServerBaseRepository => 这个类将调用 SQLDatabaseRespository。
此时在 Startup.cs 中添加对 MultiDbRepository 的依赖或根据一些设置驱动此实例化,以避免将来代码部署。
AddScoped<ICustomerBaseRespository, MultiDbBaseRepository >
因此,服务层使用 ICustomerBaseRespository,此时应用程序将调用 MultiDbBaseRepository,并且更改会更新为 SQL 和 Dynamodb,如果将来更改启动,则应用程序将调用必要的数据库。
如果我违反了设计模式,你能告诉我吗?
解决方案
此 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 中介绍了这一点。
推荐阅读
- bootstrap-4 - glyphicons 和一些引导功能在 ASP .net core 3.1 版本中不起作用
- angular - Angular 允许跨域请求
- sql-server - 如何加入多个 SQL 查询集?
- flutter - Flutter Project Failed To Compile With Compiler 消息:错误:非 ASCII 空格字符 U+00A0 只能在字符串和注释中使用
- image - 如何在从 uri 加载图像时将 gif 放入反应本机
- cobol - 此 COBOL 代码中是否存在无限循环原因?
- spring-boot - 如何从 IntelliJ 运行/部署 Spring Boot 微服务到本地 Kubernetes 集群?
- javascript - 为什么我在每个 requestAnimationFrame 处理程序之后都有“更新层树”和“复合层”任务?
- javascript - 为什么打字稿在useState反应时抛出错误
- kubernetes - 找不到 Kubernetes 容器 VolumeMounts?