Mediatr 无法解析 ASP.Net Core 中的 UserManager

Posted

技术标签:

【中文标题】Mediatr 无法解析 ASP.Net Core 中的 UserManager【英文标题】:Mediatr unable to resolve UserManager in ASP.Net Core 【发布时间】:2020-01-05 18:50:10 【问题描述】:

我正在根据这个干净的architecture 示例构建 ASP.Net Core 应用程序,该示例使用 MediatR 执行命令。 而且我想在我的应用程序中使用 ASP.Net Core Identity,所以在我的 CreateUserCommandHandler 中我想使用 UserManager 添加新用户,但是当我将 UserManager 添加到命令承包商 MediatR 时无法创建处理程序并因此异常而失败:

System.InvalidOperationException: Error constructing handler for request of type MediatR.IRequestHandler`2[GoGYM.Application.Identity.Commands.CreateUser.CreateUserCommand,MediatR.Unit]. Register your handlers with the container. See the samples in GitHub for examples. ---> System.InvalidOperationException: Unable to resolve service for type 'GoGYM.Persistence.GoGYMDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[GoGYM.Domain.Entities.ApplicationUser,GoGYM.Domain.Entities.ApplicationRole,GoGYM.Persistence.GoGYMDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim`1[System.String],Microsoft.AspNetCore.Identity.IdentityUserRole`1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin`1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken`1[System.String],Microsoft.AspNetCore.Identity.IdentityRoleClaim`1[System.String]]'.

在配置服务中,我像这样注册我的 DBContext 和 MediatR:

// Add AutoMapper
        services.AddAutoMapper(new Assembly[]  typeof(AutoMapperProfile).GetTypeInfo().Assembly );
        // Add MediatR
        services.AddMediatR(typeof(GetUsersListQueryHandler).GetTypeInfo().Assembly);
        // Add DbContext using SQL Server Provider
        services.AddDbContext<IGoGYMDbContext, GoGYMDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("NorthwindDatabase")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddDefaultTokenProviders()
             .AddEntityFrameworkStores<GoGYMDbContext>();
        services.AddMvc();
....

这是我的命令处理程序代码:

public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, Unit>

    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IGoGYMDbContext _context;

    public CreateUserCommandHandler(IGoGYMDbContext context, UserManager<ApplicationUser> userManager)
    
        _context = context;
        _userManager = userManager;
    
    public Task<Unit> Handle(CreateUserCommand request, CancellationToken cancellationToken)
    
        throw new NotImplementedException();
    

还有我的控制器

[HttpPost]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesDefaultResponseType]
    public async Task<IActionResult> Create(string values)
    
        await Mediator.Send(new CreateUserCommand(values));

        return NoContent();
    

我已经尝试了很多东西,但没有任何效果,只有当我从命令处理程序中删除 UserManager 时它才会被执行。

【问题讨论】:

CreateUserCommandHandlerGetUsersListQueryHandler 住在同一个程序集中吗? 是的,在同一个程序集中,GetUsersListQueryHandler 也可以正常工作,如果我删除了 UserManager,CreateUserCommandHandler 也可以正常工作 【参考方案1】:

您向 DI 注册 IGoGYMDbContext,但将 GoGYMDbContext 传递给 AddEntityFrameworkStoresGoGYMDbContext 未向 DI 注册,因此在 ASP.NET Core Identity 框架请求时无法解析。

以下更改允许您注册接口和实现,但无论是通过接口还是实现请求,都使用相同的实现实例

    从对AddDbContext的调用中删除接口:

    services.AddDbContext<GoGYMDbContext>(...);
    

    添加从接口到GoGYMDbContext 实现的直通:

    services.AddScoped<IGoGYMDbContext>(sp => sp.GetRequiredService<GoGYMDbContext>());
    

【讨论】:

以上是关于Mediatr 无法解析 ASP.Net Core 中的 UserManager的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core MVC 入门到精通 - 3. 使用MediatR

如何为 ASP.NET Core 注册和使用 MediatR 管道处理程序?

带有 ASP.NET Core DI 的 MediatR

ASP.NET Core MediatR 错误:向容器注册处理程序

ASP.NET Core MediatR错误:使用容器注册处理程序

MediatR CQRS - 如何处理不存在的资源(asp.net core web api)