有些服务不能在ASP中构造.. NET Core 6



我有一个错误时注入IRequestHandler

系统。AggregateException: '一些服务不能被构造(在验证服务描述符时出错')。IRequestHandler2[TabpediaFin.Handler.UnitMeasures.UnitMeasureList+Query,System.Collections.Generic.IEnumerable[TabpediaFin.Dto]。[] Lifetime: Transient ImplementationType: TabpediaFin.Handler.UnitMeasures。UnitMeasureList+QueryHandler':无法解析类型'System.Data '的服务。当尝试激活'TabpediaFin.Handler.UnitMeasures.UnitMeasureList+QueryHandler'.)'时,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;
}
}

Program.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());

}
}

您从未在容器(ServiceCollection)中注册IDbConnection,这就是为什么您得到错误

删除代码:

private readonly IDbConnection _dbConnection;

和构造函数

中的相关代码并在public async Task<IEnumerable<UnitMeasureDto>> Handle(Query req, CancellationToken cancellationToken)中创建DbManager实例

您也可以尝试将DbManager注入容器:builder.Services.AddTrainsident<DbManager>()

在Program.cs我改变了这一行

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

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