将实体从外部存储库导入到域实体的转换逻辑

问题描述 投票:0回答:1

我的域中有一个名为“服务”的实体。为了简单起见,我们假设它只有两个值对象:

服务ID(uuid) 客户端ID(uuid)

我可以通过其自己的存储库(“ServiceRepository”)访问该实体。

我的应用程序需要从外部源导入服务,但外部源中的字段需要进行一些转换,然后才能使用“ServiceRepository”保存它们。我从外部源收到这两个字段:

外部服务Id (int) 客户端代码(字符串)

在保存这些外部服务之前,我需要生成 ServiceId 并找到 ClientCode 的 ClientId。

所以,我的方法如下:

  • 使用其存储库创建两个不同的实体:“Service”和“ExternalService”。
  • 创建一个用例:
    1. 从“ExternalService”存储库获取服务
    2. 使用服务来转换来自ExternalService的数据,以便我可以使用“ServiceRepository”保存它

我的问题是这是否是最好的方法,因为我将复制实体“服务”和存储库。有什么选择可以避免这种重复吗?

domain-driven-design repository-pattern
1个回答
0
投票

请勿发布您的基础设施详细信息

这是一个假设,但听起来

code
是客户端的自然键,而
id
是RDBMS中用作主键代理键。这同样适用于
ExternalClientId
ClientId
。如果确实如此,您应该考虑从域层隐藏 id,因为它特定于您正在使用的基础设施层。如果您想更改持久化模式,或者迁移到 NoSQL 数据库,将 id 发布到域层将是一个问题,因为它们是 RDBMS 和模式依赖的概念。

如果您只将自然键发布到领域层,存储库将为您进行翻译,并且实现非常简单:

namespace Domain.ServiceContext;
public class Service
{
  public int ExternalServiceId { get; init; }
  public string ClientCode { get; init; }
  // additional service properties
}
namespace Domain.ServiceContext;
public interface IServiceRepository
{
  void Import(Domain.ServiceContext.Service service);
}
namespace Infrastructure;
public class ServiceRepository : IServiceRepository
{
  private readonly AppDbContext database;

  /// <summary>
  /// Returns the client id from the code or throws exception if not found
  /// </summary>
  private Guid FindClientId(string code) => database.Clients
    .First(client => client.Code == code)
    .Select(client => client.Id);

  /// <summary>
  /// Insert a new service and maps the client code to id
  /// </summary>
  public void Import(Domain.ServiceContext.Service service)
  {
    database.Services.Add(new Infrastructure.Model.Service
    {
      ServiceId = Guid.NewGuid(),
      ClientId = FindClientId(service.ClientCode)
      ExternalServiceId  = service.ExternalServiceId,
      // map additional properties if needed
    });
    database.SaveChanges(); // INSERT statement
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.