You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server Side中如何在自定义服务中访问UserManager<IdentityUser>?

在Blazor Server中创建可访问UserManager的自定义服务

完全可以创建这样的自定义服务,你的问题出在服务生命周期不匹配以及注册方式上,以下是正确的实现步骤:

核心问题说明

UserManager<IdentityUser> 是Scoped生命周期的服务(与每个用户会话绑定),而你尝试将自定义服务注册为Singleton(全局唯一,生命周期贯穿应用),这种跨生命周期的依赖会导致注入失败,甚至引发并发问题。

正确实现代码

1. 自定义服务类(AppWithUserManager.cs)

修正构造函数语法错误,确保正确依赖注入UserManager:

public class AppWithUserManager
{
    private readonly UserManager<IdentityUser> _userManager;

    // 构造函数注入UserManager
    public AppWithUserManager(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }

    // 示例:添加使用UserManager的业务方法
    public async Task<IdentityUser?> GetUserByIdAsync(string userId)
    {
        return await _userManager.FindByIdAsync(userId);
    }
}

2. 服务注册(Program.cs)

将自定义服务注册为Scoped(与UserManager生命周期一致),DI容器会自动解析并传递UserManager参数,无需手动填写:

// 先注册DbContext和Identity服务
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

// 注册自定义Scoped服务
builder.Services.AddScoped<AppWithUserManager>();

在Blazor组件中使用自定义服务

通过注入即可在组件中使用,示例:

@inject AppWithUserManager AppUserService
@inject AuthenticationStateProvider AuthStateProvider

<div>
    <button @onclick="LoadCurrentUser">加载当前用户</button>
    @if (CurrentUser != null)
    {
        <p>当前用户ID:@CurrentUser.Id</p>
        <p>用户名:@CurrentUser.UserName</p>
    }
</div>

@code {
    private IdentityUser? CurrentUser;

    private async Task LoadCurrentUser()
    {
        var authState = await AuthStateProvider.GetAuthenticationStateAsync();
        var claimsUser = authState.User;
        
        if (claimsUser.Identity?.IsAuthenticated == true)
        {
            CurrentUser = await AppUserService.GetUserByIdAsync(claimsUser.FindFirst(ClaimTypes.NameIdentifier)!.Value);
        }
    }
}

注意事项

  • 禁止将依赖Scoped服务的自定义服务注册为Singleton或Transient(Transient虽不会报错,但会导致每次创建服务时生成新的UserManager实例,不符合Identity的设计)
  • 确保Identity服务已正确配置(包括DbContext关联),否则UserManager无法被DI容器解析

内容的提问来源于stack exchange,提问作者Ben Junior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:10:22