某些服务无法在 ASP.NET Core 6 中构建

问题描述 投票:0回答:3

注入 IRequestHandler 时出现错误

System.AggregateException:'某些服务无法构建(验证服务描述符时出错'ServiceType:MediatR.IRequestHandler

2[TabpediaFin.Handler.UnitMeasures.UnitMeasureList+Query,System.Collections.Generic.IEnumerable
1[TabpediaFin.Dto.UnitMeasureDto]]生命周期:瞬态实现类型:TabpediaFin.Handler.UnitMeasures .UnitMeasureList+QueryHandler':尝试激活“TabpediaFin.Handler.UnitMeasures.UnitMeasureList+QueryHandler”时无法解析类型“System.Data.IDbConnection”的服务。)'

DbManager.cs

using Npgsql;

namespace TabpediaFin.Infrastructure.Data;

public class DbManager
{
    private readonly string _connectionString;

    public DbManager(IConfiguration config)
    {
        _connectionString = config.GetConnectionString("DefaultConnection") ?? string.Empty;
    }

    public string ConnectionString => _connectionString;

    public IDbConnection CreateConnection()
    {
        IDbConnection cn = new NpgsqlConnection(_connectionString);

        DefaultTypeMap.MatchNamesWithUnderscores = true;
        // SimpleCRUD.SetDialect(SimpleCRUD.Dialect.PostgreSQL);

        return cn;
    }
}

程序.cs

using FluentValidation.AspNetCore;
using Serilog;
using Serilog.Sinks.SystemConsole.Themes;
using System.Reflection;
using TabpediaFin.Infrastructure.Data;
using MediatR;
using TabpediaFin.Infrastructure.Validation;
using TabpediaFin.Infrastructure;
using Microsoft.AspNetCore.Builder;
using TabpediaFin.Infrastructure.OpenApi;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using TabpediaFin.Infrastructure.Migrator;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Npgsql;

Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Verbose()
            .Enrich.FromLogContext()
            .WriteTo.Console(
                outputTemplate:
                "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}",
                theme: AnsiConsoleTheme.Code)
    .CreateBootstrapLogger();

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog();

builder.Services.AddMediatR(Assembly.GetExecutingAssembly());
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationPipelineBehavior<,>));

builder.Services.AddDbMigrator();

builder.Services.AddDbContext<FinContext>();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.RegisterSwagger("Tabpedia Finance", "v1");

builder.Services.AddControllers(options =>
    {
        options.Filters.Add<ValidateModelFilter>();
    })
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    })
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    });

builder.Services.AddFluentValidationAutoValidation();

builder.Services.AddCors();

builder.Services.RegisterSettings(builder.Configuration);
builder.Services.RegisterServices();
builder.Services.RegisterRepositories();
//builder.Services.AddScoped<IDbConnection>(db => new NpgsqlConnection(Configuration.GetConnectionString("AppConnectionString")));

builder.Services.AddJwt();

var app = builder.Build();

app.UseMiddlewares();

// Configure the HTTP request pipeline.
// if (app.Environment.IsDevelopment())
// {
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Tabpedia Finance v1"));
// }

app.UseHttpsRedirection();

app.UseRouting();

app.UseCors(
    builder =>
        builder.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod()
            .WithExposedHeaders("Token-Expired"));

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

app.MapControllers();

using (var scope = app.Services.CreateScope())
{
    TabpediaFin.Infrastructure.Migrator.Startup.UpdateDatabase(scope.ServiceProvider);
}

app.Run();

UnitMeasureList.cs

using Microsoft.EntityFrameworkCore;

namespace TabpediaFin.Handler.UnitMeasures
{
    public class UnitMeasureList 
    {
        public class Query : IRequest<IEnumerable<UnitMeasureDto>>
        { }

        public class QueryHandler : IRequestHandler<Query, IEnumerable<UnitMeasureDto>>
        {
            private readonly IDbConnection _dbConnection;
            private readonly ICurrentUser _currentUser;

            public QueryHandler(
                IDbConnection connection,
                ICurrentUser currentUser)
            {
                _dbConnection = connection;
                _currentUser = currentUser;
            }
            public async Task<IEnumerable<UnitMeasureDto>> Handle(Query req, CancellationToken cancellationToken)
            {
                string sql = $@"SELECT 
                                    um.*, at.Id, au.Id 
                                    FROM UnitMeasure um 
                                    INNER JOIN AppTenant at ON at.Id = um.Id
                                    INNER JOIN AppUser au ON au.Id = um.Id ";

                var unitMeasure = await _dbConnection.QueryAsync<UnitMeasureDto>(sql, new {
                    userName = _currentUser.Username
                });
                return unitMeasure.ToList();
            }
        }
    }
}

UnitMeasureDto.cs

namespace TabpediaFin.Dto
{
    public class UnitMeasureDto
    {
        protected UnitMeasureDto(
            int id
            ,int tenantId 
            ,string name 
            ,string description 
            ,int createdUid 
            ,DateTime createdUtc 
            ,int updatedUid 
            ,DateTime updatedUtc 
            )
        {
            Id = id;
            TenantId = tenantId;
            Name = name;
            Description = description;
            CreatedUid = createdUid;
            CreatedUtc = createdUtc;
            UpdatedUid = updatedUid;
            UpdatedUtc = updatedUtc;

        }
        public int Id { get; set; }
        public int TenantId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int CreatedUid { get; set; }
        public DateTime CreatedUtc { get; set; }
        public int UpdatedUid { get; set; }
        public DateTime UpdatedUtc { get; set; }

    }
}

UnitMeasuresController.cs

namespace TabpediaFin.Handler.UnitMeasures
{
    [Route("api/[controller]")]
    [ApiController]
    public class UnitMeasuresController : ControllerBase
    {
        private readonly IMediator _mediator;

        public UnitMeasuresController(
            IMediator mediator)
        {
            _mediator = mediator;
        }

        [HttpGet]
        public async Task<IEnumerable<UnitMeasureDto>> Get() => await _mediator.Send(new UnitMeasureList.Query());



    }
}
c# cqrs asp.net-core-6.0 mediatr
3个回答
1
投票

在Program.cs中 我改变了这一行

//builder.Services.AddScoped<IDbConnection>(db => new NpgsqlConnection(Configuration.GetConnectionString("AppConnectionString")));

到此

builder.Services.AddScoped<IDbConnection>(db => new NpgsqlConnection(builder.Configuration.GetConnectionString("AppConnectionString")));

0
投票

您从未在容器(ServiceCollection)中注册IDbConnection,这就是您收到错误的原因

删除代码:

private readonly IDbConnection _dbConnection;

以及构造函数中的相关代码

并在

public async Task<IEnumerable<UnitMeasureDto>> Handle(Query req, CancellationToken cancellationToken)

中创建 DbManager 的实例

您也可以尝试将 DbManager 注入到容器中:

builder.Services.AddTrainsident<DbManager>()


0
投票

这是一个带有注释的很好的例子 使用 AnnationServiceBilder.Annotations.Transient_Services;

[TransientService]
public class MyTransientService
{
    // Implementation...
}

https://github.com/genryianchev/AnnationServiceBilder/tree/main

© www.soinside.com 2019 - 2024. All rights reserved.