abp vnext blog模块用户信息同步 源码解析

先看一下Volo.Blogging.Domain引用的关于用户的项目只有Volo.Abp.Users.Domain,再看BlogUser定义:

    public class BlogUser : AggregateRoot<Guid>, IUser, IUpdateUserData
    {
        public virtual Guid? TenantId { get; protected set; }
...

先记下这个点:IUpdateUserData ,查看源码

public interface IUpdateUserData
{
    bool Update([NotNull] IUserData user);
}

查看文件BlogUserLookupService

    public class BlogUserLookupService : UserLookupService<BlogUser, IBlogUserRepository>, IBlogUserLookupService
    {
        public BlogUserLookupService(
            IBlogUserRepository userRepository,
            IUnitOfWorkManager unitOfWorkManager)
            : base(
                userRepository,
                unitOfWorkManager)
        {
            
        }

        protected override BlogUser CreateUser(IUserData externalUser)
        {
            return new BlogUser(externalUser);
        }
    }

啥也没干就继承了泛型类UserLookupService,重点看UserLookupService类,这个类有三个主要方法:FindByIdAsync,FindByUserNameAsync,SearchAsync,主要看下FindByIdAsync方法:

    public async Task<TUser> FindByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {

        // _userRepository继承类的泛型,对应IBlogUserRepository,localUser 指blog模块中的用户信息
        var localUser = await _userRepository.FindAsync(id, cancellationToken: cancellationToken);
        // IExternalUserLookupServiceProvider搜索整个源码文件只用IdentityUserRepositoryExternalUserLookupServiceProvider和HttpClientExternalUserLookupServiceProvider实现这个接口,
        // 一般情况下这个应该不为空,如果ExternalUserLookupServiceProvider为空,即返回
        if (ExternalUserLookupServiceProvider == null)
        {
            return localUser;
        }

        // SkipExternalLookupIfLocalUserExists在UserLookupService默认为true,其他地方未修改
        // 本地bloguser不存在且SkipExternalLookupIfLocalUserExists返回bloguser
        if (SkipExternalLookupIfLocalUserExists && localUser != null)
        {
            return localUser;
        }
        IUserData externalUser;

        try
        {
            // 使用ExternalUserLookupServiceProvider方法获取User数据,这个ExternalUserLookupServiceProvider是IdentityUserRepositoryExternalUserLookupServiceProvider
            // 
            externalUser = await ExternalUserLookupServiceProvider.FindByIdAsync(id, cancellationToken);
            // IdentityUserRepositoryExternalUserLookupServiceProvider也不存在User信息
            if (externalUser == null)
            {
                // 删除bloguser
                if (localUser != null)
                {
                    //TODO: Instead of deleting, should be make it inactive or something like that?
                    await WithNewUowAsync(() => _userRepository.DeleteAsync(localUser, cancellationToken: cancellationToken));
                }

                return null;
            }
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            return localUser;
        }
        // externalUser 不为空。bloguser为空,插入bloguser库
        if (localUser == null)
        {
            await WithNewUowAsync(() => _userRepository.InsertAsync(CreateUser(externalUser), cancellationToken: cancellationToken));
            return await _userRepository.FindAsync(id, cancellationToken: cancellationToken);
        }
        // bloguser不为空,实现IUpdateUserData接口且存在更新内容,则更新bloguser数据
        if (localUser is IUpdateUserData && ((IUpdateUserData)localUser).Update(externalUser))
        {
            await WithNewUowAsync(() => _userRepository.UpdateAsync(localUser, cancellationToken: cancellationToken));
        }
        else
        {
            return localUser;
        }

        return await _userRepository.FindAsync(id, cancellationToken: cancellationToken);
    }


到此位置,当在blog模块中调用UserLookupService时,获取到的用户信息是和Identity模块中用户信息是同步的,Identity有blog没的添加一个,Identity没blog有删除一个,Identity和blog不一样的更新到blog一个,然后再看看BlogUserSynchronizer类,这个类订阅一个事件:

public async Task HandleEventAsync(EntityUpdatedEto<UserEto> eventData)
{
  // 本地库bloguser查找
   var user = await UserRepository.FindAsync(eventData.Entity.Id);
   if (user == null)
   {       
       // 本地查不到,看看Identity里有没,
       user = await UserLookupService.FindByIdAsync(eventData.Entity.Id);
       if (user == null)
       {
          return;
       }
   }
   // 不管哪有,最后更新到bloguser库里
   if (user.Update(eventData.Entity))
   {
       await UserRepository.UpdateAsync(user);
   }
}

至此,完成所有同步工作。

貌似还有点糊涂,欢迎大家指导!

 

posted @ 2022-12-17 21:54  indexlang  阅读(143)  评论(0编辑  收藏  举报