.Net Core - 多后端系统的存储库模式
.Net Core - Repository Pattern for Multiple Backend Systems
我正在创建一个具有多层的 .Net Core API
Customer.API
Customer.Business
客户服务
Customer.Libs
这 API 此时必须调用 2 个数据库系统(相同的更新应该发送到两个系统)并且在不久的将来其中一个系统将被停用。
- DynamoDB
- SQL 服务器
我创建了如下所示的存储库层,想知道这是否是正确的方法。
创建一个抽象层并在 Customer.Libs
中有像这样的 classes
MultiDbBaseRepository.cs
SQlServerBaseRepository.cs
MultiDbBaseRepository => 此 class 将同时调用存储库 classes SQLDatabaseRespository 和 DynamoDbRepository
SQlServerBaseRepository => 此 class 将调用 SQLDatabaseRespository。
此时在 Startup.cs 中添加对 MultiDbRepository 的依赖或根据某些设置驱动此实例化,以避免将来进行代码部署。
AddScoped
因此,服务层使用 ICustomerBaseRespository,此时应用程序将调用 MultiDbBaseRepository,并且更改会更新到 SQL 和 Dynamodb,如果将来更改启动,则应用程序将调用必要的数据库。
如果我违反了设计模式,你能告诉我吗?
This API has to call 2 Database Systems at this moment (same updates should go to both the systems) and in near future one of the Systems will be decommissioned.
这几乎就是我在我的视频Composite as Universal Abstraction. In short, you can use the Composite 设计模式中针对此(以及许多其他)场景涵盖的场景。
我从一些 class 名称中猜测存储库应该与客户打交道,所以这样的事情可能是有道理的:
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);
}
}
您还必须在另外两个 class 中实现 ICustomerRepository
接口,这些接口与所讨论的两个数据库系统对话:
public class DynamoDBCustomerRepository : ICustomerRepository { /*...*/ }
public class SqlServerCustomerRepository : ICustomerRepository { /*...*/ }
现在从特定的实现中组成一个存储库:
ICustomerRepository repo = new CompositeCustomerRepository(sqlRepo, dynamoRepo);
所有客户端都应该与 ICustomerRepository
接口而不是具体类型对话。客户将不会意识到他们正在与一个复合数据库而不是单个数据库对话。这将使以后退役其中之一变得微不足道。
正如我在视频中所述,如果您的存储库还需要 读取 数据库中的实体,您必须决定要从哪个数据库读取 return 数据。一种选择是选择您可以找到的第一个非空结果。我也在我的视频和文章 Coalescing Composite as a monoid.
中介绍了这一点
我正在创建一个具有多层的 .Net Core API
Customer.API
Customer.Business
客户服务
Customer.Libs
这 API 此时必须调用 2 个数据库系统(相同的更新应该发送到两个系统)并且在不久的将来其中一个系统将被停用。
- DynamoDB
- SQL 服务器
我创建了如下所示的存储库层,想知道这是否是正确的方法。
创建一个抽象层并在 Customer.Libs
中有像这样的 classesMultiDbBaseRepository.cs
SQlServerBaseRepository.cs
MultiDbBaseRepository => 此 class 将同时调用存储库 classes SQLDatabaseRespository 和 DynamoDbRepository SQlServerBaseRepository => 此 class 将调用 SQLDatabaseRespository。
此时在 Startup.cs 中添加对 MultiDbRepository 的依赖或根据某些设置驱动此实例化,以避免将来进行代码部署。
AddScoped
因此,服务层使用 ICustomerBaseRespository,此时应用程序将调用 MultiDbBaseRepository,并且更改会更新到 SQL 和 Dynamodb,如果将来更改启动,则应用程序将调用必要的数据库。
如果我违反了设计模式,你能告诉我吗?
This API has to call 2 Database Systems at this moment (same updates should go to both the systems) and in near future one of the Systems will be decommissioned.
这几乎就是我在我的视频Composite as Universal Abstraction. In short, you can use the Composite 设计模式中针对此(以及许多其他)场景涵盖的场景。
我从一些 class 名称中猜测存储库应该与客户打交道,所以这样的事情可能是有道理的:
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);
}
}
您还必须在另外两个 class 中实现 ICustomerRepository
接口,这些接口与所讨论的两个数据库系统对话:
public class DynamoDBCustomerRepository : ICustomerRepository { /*...*/ }
public class SqlServerCustomerRepository : ICustomerRepository { /*...*/ }
现在从特定的实现中组成一个存储库:
ICustomerRepository repo = new CompositeCustomerRepository(sqlRepo, dynamoRepo);
所有客户端都应该与 ICustomerRepository
接口而不是具体类型对话。客户将不会意识到他们正在与一个复合数据库而不是单个数据库对话。这将使以后退役其中之一变得微不足道。
正如我在视频中所述,如果您的存储库还需要 读取 数据库中的实体,您必须决定要从哪个数据库读取 return 数据。一种选择是选择您可以找到的第一个非空结果。我也在我的视频和文章 Coalescing Composite as a monoid.
中介绍了这一点