AggregateException: 一些服务无法被构建

5

我有一个使用.NET 5.0的项目,一切都很好 - 构建、执行、工作正常 - 直到4月10日。

现在我遇到了很多注册服务方面的错误。

Unhandled exception. System.AggregateException: Some services are not able to be constructed 
(Error while validating the service descriptor 'ServiceType: AService.DataAccess.MyDbContext 
Lifetime: Scoped ImplementationType: AService.DataAccess.MyDbContext': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbSet`1[AService.Domain.Entities.B.B]' while 
attempting to activate 'AService.DataAccess.MyDbContext'.) (Error while validating the 
service descriptor 'ServiceType: 
MediatR.IRequestHandler`2[AService.Api.Queries.B.GetAllQuery, 
System.Collections.Generic.IEnumerable`1[AService.Api.Queries.B.Dtos.BDto]] 
Lifetime: Transient ImplementationType: 
AService.Queries.B.GetAllQueryHandler': Unable to resolve service for type 
'Microsoft.EntityFrameworkCore.DbSet`1[AService.Domain.Entities.B.B]' while 
attempting to activate 'AService.DataAccess.MyDbContext'.)

简而言之,每个存储库、服务和需要注册的所有内容都在以下代码中注册:Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(options => 
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

    services.AddDbContext<MyDbContext>();
    
    services.AddStackExchangeRedisExtensions<NewtonsoftSerializer>((options) => 
        Configuration.GetSection("Redis").Get<RedisConfiguration>());
    
    services.AddMediatR(Assembly.GetExecutingAssembly());

    services.AddTransient<IARepository, ARepository>();
    services.AddTransient<IBRepository, BRepository>();
    services.AddTransient<ICRepository, CRepository>();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo {Title = "Service API", Version = "v1.0"});
    });

}


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();
    app.UseRouting();
    app.UseCors();

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

    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "Menu Service API v1.0");
    });
}

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}

我不知道是否是Rider版本的问题(我在macos上编程)。当我调试时,出现以下错误消息:

当前本机IP地址下没有可用的IL变量(0x80131304)。错误代码为CORDBG_E_IL_VAR_NOT_AVAILABLE或0x80131304。

有人有什么想法可以导致这个错误吗?正如我一开始所说,几天前一切都正常工作。

编辑-添加了MyDbContext:

public class MyDbContext : DbContext
{
    public MyDbContext(DbSet<A> a, DbSet<B> b, DbSet<C> c)
    {
        As = a;
        Bs = b;
        Cs = c;
    }

    public DbSet<A> As { get; }
    public DbSet<B> Bs { get; }
    public DbSet<C> Cs { get; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=localhost;Database=my-db;User=user;Password=password");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<B>()
            .HasOne(mi => mi.A)
            .WithMany(m => m.Bs)
            .HasForeignKey(mi => mi.AId);

        modelBuilder.Entity<B>()
            .Property(mi => mi.Xs)
            .HasConversion(
                a => string.Join(',', a),
                a => a.Split(',', StringSplitOptions.RemoveEmptyEntries));
    }
}

请问您能否添加 MyDbContext 的代码? - Guru Stron
我已经编辑了主贴。 - paweto
2
你应该从你的数据库上下文中移除构造函数。 - Guru Stron
我的天啊...Rider的编码提示真是太棒了...我花了两天时间才搞明白出了什么问题。你知道这是为什么会造成这样的问题吗? - paweto
错误信息“明确”表示:您的服务定位器无法构造DbContext。原因是,服务定位器无法注入DbSet<A> a、DbSet<B> b和DbSet<C> c,除非您在Startup.cs中的ConfigureService()方法中注册这些内容。或者,您可以通过提供一个方法来覆盖您的dbcontext的创建代码,通过AddDbContext参数。 - ˈvɔlə
2个回答

6

移除构造函数并添加设置器到DbSet属性:

public class MyDbContext : DbContext
{
    public DbSet<A> As { get; private set; } // or public setters
    public DbSet<B> Bs { get; private set; }
    public DbSet<C> Cs { get; private set; }
    .....
}

DI容器使用构造函数实现其魔法,并尝试解析和注入所有构造函数参数。由于您尚未注册DbSet,因此它们无法被解析(且不应该注册)。


0
检查相关服务类的构造函数并删除任何字符串值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接