【问题标题】:Add identity UserId property into my domain entity将身份 UserId 属性添加到我的域实体中
【发布时间】:2021-11-21 07:44:37
【问题描述】:

我遇到了将 UserId 属性从我的 ApplicationUser 添加到域 Player 实体的问题。

这是我的域实体 Player,我有虚拟 ApplicationUserId 属性。 在 UserService 中创建 User 后,我有一个想法写 UserId,但由于 setter 的保护级别而无法继续。我应该更改删除保护级别还是有其他方法来获得结果?

也许我应该在像 SetUserId 这样的域中创建一个方法,在那里我将使用来自 IdentityServer.CreateUser 的 UserId 设置私有属性?好方法吗?

public class Player: MyEntity
    {
        public string UserName { get; private set; }

        public virtual Guid ApplicationUserId { get; private set; }

        private Player() 
        { }

      
    }

UserService.cs sn-p 用户正在创建的位置

public async Task<(AppSignInResult result, SignInData data)> CreateUser(string username, string password, string email, string country)
        {
            var user = new ApplicationUser() { UserName = username, Email = email};

            var result = await _userManager.CreateAsync(user, password);

          ...
             // here is call of mediatr command

            var command = new CreatePlayerCommand(username, country);

           var id = await _mediator.Send(command);

         ...

            return ...
        }

CreatePlayerCommand.Handle 处理程序代码

  public async Task<int> Handle(CreatePlayerCommand request, CancellationToken cancellationToken)
           {
               var player = new Player(
                   request.userName);

               _unitOfWork.Players.Add(player);
               await _unitOfWork.SaveChanges();

               return player.Id;
           }

【问题讨论】:

    标签: c# .net domain-driven-design identityserver4


    【解决方案1】:

    我在域实体中创建了方法

     private void SetUserId(Guid userId)
            {
                ApplicationUserId = userId;
            }
    

    传入CreatePlayerCommand 并从_userManager.CreateAsync 结果传递用户ID。它按预期工作。

    【讨论】:

    • 将在此处传递字符串并继续验证解析此字符串 -> guid 以保持 DDD 方法。有什么想法吗?
    【解决方案2】:

    为什么需要设置 Player.ApplicationUserId?您可以在构造函数或数据库中生成它。为什么要改id?如果您仅从 CreateUser 命令访问,则不需要它。因为 id 不是来自客户端。你应该像这样自动生成:

    Player(string userName, ...)
    {     
        ApplicationUserId = Guid.NewGuid();
        UserName = userName;
        ...
    
    }
    

    【讨论】:

    • 但是我已经从 _userManager.CreateAsync 方法创建了 Id,它作为主键存储在 AspNetUsers 表的 DB 中。我需要 AspNetUser Player 的 1:1 关系。
    • 不过,您不需要在任何地方设置 ApplicationUserId 属性。见:stackoverflow.com/questions/42573214/…
    • 我已经实现了您的建议,只需在 _userManager.CreateUser 之前放置创建域播放器的命令,并在播放器构造函数中创建 Id = guid 的 ApplicationUser 对象。它奏效了!
    • 还有一个问题,如果我将我的 Id 类型从 Guid 更改为 int 并且我不能像 Guid.NewGuid(); 那样创建?我应该将它传递给构造函数参数并这样做吗? Player(..., int userId) { ApplicationUserId = userId}
    • 如果使用 Id 作为整数,则应从数据库中设置自增整数。然后,除了更改 Id 类型外,您无需在应用程序端进行任何更改。如果您的 id 没有意义,例如 GSM 号码、电子邮件或公民号码,则在创建实体时从客户端获取 ID 不是一个好习惯。
    【解决方案3】:

    虽然对于这类问题没有最好的想法,但这个问题可以设计成类似_buyerId 的顺序类。请先看链接。

    _buyerId 应该在订单类中设置,因为它是一个私有字段。此外,例如,对于通过 EF 持久化 _buyerId,可以在 orderConfiguration 中进行配置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-11
      • 2015-02-10
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多