首页 > 解决方案 > 使用 DDD for User Domain 模型生成 ID 和密码散列的最佳方法

问题描述

我是 DDD 的新手,现在我正在实施用户注册。

基本上流程是:

  1. 控制器接收请求
  2. 将从客户端接收到的数据映射到用户域模型。
  3. 将用户域模型映射到 EF 核心实体模型。
  4. 使用 EF-Core 将用户添加到数据库。

IdGeneratorService我对我在哪里上课和上课有一些疑问BCryptService。目前它们都在领域层有一个接口:src/Domain/Model/Services. 他们的实现驻留在我的基础设施层中:src/Infrastructure/Services. 它们也在用户域模型中被调用:

public class User
{
    private User(
        long id, 
        string name, 
        string lastName, 
        string contactPhone, 
        string contactEmail, 
        string userName, 
        string password)
    {
        Id = id;
        Name = name;
        LastName = lastName;
        ContactPhone = contactPhone;
        ContactEmail = contactEmail;
        UserName = userName;
        Password = password;
    }

    public IEnumerable<Role> Type { get; set; }

    public static async Task<User> ConstructAsync(
        string name, string lastName, 
        string contactPhone, string contactEmail, 
        string userName, string password, 
        IIdGeneratorService<long> idGeneratorService, IBCryptService bCryptService)
    {
        var id = await idGeneratorService.GenerateAsync();

        password = bCryptService.HashPassword(password);

        return new User(id, name, lastName, contactPhone, contactEmail, userName, password); 
    } 

这是由我的控制器调用的:

[HttpPost("[Action]")]
public async Task<IActionResult> Create([FromBody] UserModel userModel)
{
    var user = 
        await DomainUser.ConstructAsync(
            userModel.Name, userModel.LastName,
            userModel.ContactPhone, userModel.ContactEmail,
            userModel.UserName, userModel.Password,
            _idGeneratorService, _bCryptService);

    await _userRepository.AddAsync(user);

    return sampleResponse;
}

我觉得在域模型中调用 IdGenerator 和 BCrypt 是不好的做法,因为据我了解,域层无法了解基础设施层,所以我不太确定我该怎么做。非常感谢根据您在此处理解的有关其他实现的任何其他帮助/建议。

标签: c#.net-coredomain-driven-designcng

解决方案


在控制器和域层之间引入一个中间“应用程序服务”层是一种很好的做法。

应用服务将负责调用(注入的)基础设施服务、调用领域层以及持久化/加载必要的数据。Controller 的职责只是收集请求参数,确保身份验证(如果需要),然后调用 Application Service 方法。

应用程序服务是领域模型的直接客户,并作为中介在外部世界和领域层之间进行协调。他们负责处理基础设施问题,如 ID 生成、事务管理、加密等。这些职责也不是控制器层的问题。

应用程序服务通常还为 API 进行任务协调(每个 API 一个服务方法)。使用 ACID 数据库时,相同的服务还控制事务,确保模型状态转换以原子方式持久化。

在您的具体示例中,应用服务将负责调用 IdGeneratorService 和 BCryptService,获取输出并将它们作为参数发送到域层。就域层而言,它确实需要知道 ID 或密码是如何生成的——这些不是域问题。因此,它很乐意忽略这些基础设施方面,而只会让自己承担用户行为的任务。


推荐阅读