asp.net System.AggregateException:某些服务无法构建

v6ylcynt  于 2023-05-19  发布在  .NET
关注(0)|答案(1)|浏览(377)

我正在使用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我将非常感谢任何帮助!

efzxgjgh

efzxgjgh1#

您的依赖注入设置中缺少一些注册。
抛出的聚合异常显示3个内部异常。
其中2个指示没有注册IMapper(看起来您正在使用Mapster)。
在Program.cs中的AddDbContext调用上方添加以下内容(有关更多信息,请参阅此处):

builder.Services.AddMapster()

这应该会处理聚合异常中的前两个错误。
第三个异常指示没有注册UserManager<Domain.Models.User>。您的类Tavrida.Backend.Auth.Users.Queries.AuthUser.LoginDefault.LoginDefaultQueryHandler显然有一个UserManager类型的构造函数参数<Domain.Models.User>,但您的主机不知道如何创建该对象类型。
考虑到您正在使用自己的自定义实现的用户模型(Domain.Models.User),请确保此类实现ASP.NETCoreIdentityUser类中的内置

using System;
using Microsoft.AspNetCore.Identity;

public class User : IdentityUser<Guid>
{
   // your custom properties here
}

然后在Program.cs中,下面的代码将为您注册DI中的ASP.NET Core标识相关类,例如UserManager。

builder.services.AddDefaultIdentity<Domain.Models.User>()
app.UseAuthentication();
app.UseAuthorization();

我建议使用reviewing the ASP.Net Core Identity documentation作为使用内置功能实现身份的推荐方法。

相关问题