我正在使用MediatR 12.0.1库编写一个关于ASP-NET Core的项目。我是.net 6的新手,我正在学习依赖注入。Structure
using Application;
using Application.Common;
using Domain;
using Domain.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
namespace Tavrida.Backend
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(opt =>
{
if (builder.Environment.IsDevelopment())
opt.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"));
if (builder.Environment.IsProduction())
{
var database = Environment.GetEnvironmentVariable("PGDATABASE");
var host = Environment.GetEnvironmentVariable("PGHOST");
var user = Environment.GetEnvironmentVariable("PGUSER");
var password = Environment.GetEnvironmentVariable("PGPASSWORD");
var port = Environment.GetEnvironmentVariable("PGPORT");
var connection = $"User ID={user};Password={password};Host={host};Port={port};Database={database}";
opt.UseNpgsql(connection);
}
});
builder.Services.AddScoped<IForumContext>(provider => provider.GetService<AppDbContext>());
builder.Services.AddScoped<IModelContext>(provider => provider.GetService<AppDbContext>());
builder.Services.AddScoped<IUserContext>(provider => provider.GetService<AppDbContext>());
using (var scope = builder.Services.BuildServiceProvider())
{
try
{
var context = scope.GetRequiredService<AppDbContext>();
DbInitializer.Initialize(context);
}
catch (Exception exception)
{
var logger = scope.GetRequiredService<ILogger<Program>>();
logger.LogError(exception, "An error occurred while app initialization");
}
}
builder.Services.AddApplicationModule();
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run();
}
}
}
此项目的生成是成功的,但在运行时它调用System.AggregateException
System.AggregateException: "Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler`2[Application.Forums.Queries.GetForumList.GetForumListQuery,Application.Forums.Queries.GetForumList.ForumListVm] Lifetime: Transient ImplementationType: Application.Forums.Queries.GetForumList.GetForumListQueryHandler': Unable to resolve service for type 'MapsterMapper.IMapper' while attempting to activate 'Application.Forums.Queries.GetForumList.GetForumListQueryHandler'.) (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler`2[Application.Forums.Queries.GetForumDetail.GetForumDetailQuery,Application.Forums.Queries.GetForumDetail.ForumDetailVm] Lifetime: Transient ImplementationType: Application.Forums.Queries.GetForumDetail.GetForumDetailQueryHandler': Unable to resolve service for type 'MapsterMapper.IMapper' while attempting to activate 'Application.Forums.Queries.GetForumDetail.GetForumDetailQueryHandler'.) (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler`2[Tavrida.Backend.Auth.Users.Queries.AuthUser.LoginDefault.LoginDefaultQuery,System.IdentityModel.Tokens.Jwt.JwtSecurityToken] Lifetime: Transient ImplementationType: Tavrida.Backend.Auth.Users.Queries.AuthUser.LoginDefault.LoginDefaultQueryHandler': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Domain.Models.User]' while attempting to activate 'Tavrida.Backend.Auth.Users.Queries.AuthUser.LoginDefault.LoginDefaultQueryHandler'.)"
我的一个接头人的密码
using Domain.Interfaces;
using Mapster;
using MapsterMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Forums.Queries.GetForumList
{
public class GetForumListQueryHandler : IRequestHandler<GetForumListQuery, ForumListVm>
{
private readonly IForumContext _context;
private readonly IMapper _mapper;
public GetForumListQueryHandler(IForumContext context, IMapper mapper) =>
(_context, _mapper) = (context, mapper);
public async Task<ForumListVm> Handle(GetForumListQuery request, CancellationToken cancellationToken)
{
var forums = await _mapper.From(_context.Forums
.OrderBy(x => x.StartedAt)
.Skip(request.Skiped)
.Take(request.Count))
.ProjectToType<ForumDto>()
.ToListAsync(cancellationToken);
return new ForumListVm { ForumList = forums };
}
}
}
using MediatR;
namespace Application.Forums.Queries.GetForumList
{
public class GetForumListQuery : IRequest<ForumListVm>
{
public int Count { get; set; }
public int Skiped { get; set; }
}
}
namespace Application.Forums.Queries.GetForumList
{
public class ForumListVm
{
public IList<ForumDto>? ForumList { get; set; }
}
}
namespace Application.Forums.Queries.GetForumList
{
public class ForumDto
{
public string? Id { get; set; }
public string? Title { get; set; }
public string? LogoUrl { get; set; }
}
}
要注册服务,我使用类
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
namespace Application
{
public static class ApplicationModule
{
public static IServiceCollection AddApplicationModule(this IServiceCollection services)
{
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
return services;
}
}
}
我使用以下代码将MediatoR库添加到控制器
private IMediator _mediator;
protected IMediator Mediator =>
_mediator ??= HttpContext.RequestServices.GetService<IMediator>();
我尝试了不同的MediatR注册方法。我所有的尝试都以两种情况结束:
1.找不到MediatR类型请求的处理程序。IRequestHandler
1.验证服务描述符“ServiceType”时出错:MediatR.IRequestHandler
我读了一篇类似的文章,但我不知道如何解决我的问题。Article我将非常感谢任何帮助!
1条答案
按热度按时间efzxgjgh1#
您的依赖注入设置中缺少一些注册。
抛出的聚合异常显示3个内部异常。
其中2个指示没有注册IMapper(看起来您正在使用Mapster)。
在Program.cs中的AddDbContext调用上方添加以下内容(有关更多信息,请参阅此处):
这应该会处理聚合异常中的前两个错误。
第三个异常指示没有注册UserManager<Domain.Models.User>。您的类Tavrida.Backend.Auth.Users.Queries.AuthUser.LoginDefault.LoginDefaultQueryHandler显然有一个UserManager类型的构造函数参数<Domain.Models.User>,但您的主机不知道如何创建该对象类型。
考虑到您正在使用自己的自定义实现的用户模型(Domain.Models.User),请确保此类实现ASP.NETCoreIdentityUser类中的内置
然后在Program.cs中,下面的代码将为您注册DI中的ASP.NET Core标识相关类,例如UserManager。
我建议使用reviewing the ASP.Net Core Identity documentation作为使用内置功能实现身份的推荐方法。