Autofac泛型仓储多DbContext注册异常问题求助
C#项目使用Ardalis Specification库,需操作两个不同的DbContext。在Autofac中注册实现IRepository、IReadRepository的泛型仓储后,使用关联SapScriptDbContext的仓储时抛出异常:
System.ArgumentException: Cannot create a DbSet for 'CooisHeader' because this type is not included in the model for the context.
相关代码
仓储与DbContext实现
public class AppEfRepository<T> : RepositoryBase<T>,IReadRepository<T>,IRepository<T> where T : class,IAggregateRoot { public AppEfRepository(ApplicationDbContext context):base(context) { } } public class SapScriptDbContext : DbContext { public SapScriptDbContext(DbContextOptions<SapScriptDbContext> options):base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<CooisHeader>().ToTable("CooisHeader"); modelBuilder.Entity<CooisComponent>().ToTable(nameof(CooisComponent)); } public DbSet<CooisHeader> CooisHeader => Set<CooisHeader>(); public DbSet<CooisComponent> CooisComponent => Set<CooisComponent>(); }
Autofac注册模块
public class AutofacInfrastructureModule : Module { private readonly List<Assembly> _assemblies = new List<Assembly>(); public AutofacInfrastructureModule(Assembly? callingAssembly = null) { AddToAssembliesifNotNull(callingAssembly); } private void AddToAssembliesifNotNull(Assembly callingAssembly) { if (callingAssembly != null) { _assemblies.Add(callingAssembly); } } protected override void Load(ContainerBuilder builder) { LoadAssemblies(); RegisterEf(builder); } private void LoadAssemblies() { var coreAssembly = Assembly.GetAssembly(typeof(CooisHeader)); var appCore = Assembly.GetAssembly((typeof(Cut))); var infrastructureAssembly = Assembly.GetAssembly(typeof(AutofacInfrastructureModule)); AddToAssembliesifNotNull(coreAssembly); AddToAssembliesifNotNull(appCore); AddToAssembliesifNotNull(infrastructureAssembly); } private void RegisterEf(ContainerBuilder builder) { builder.RegisterGeneric(typeof(SapScriptEfRepository<>)) .As(typeof(IRepository<>)) .As(typeof(IReadRepository<>)) .InstancePerLifetimeScope(); // 注释掉下面这段代码时程序可正常运行 builder.RegisterGeneric(typeof(AppEfRepository<>)) .As(typeof(IRepository<>)) .As(typeof(IReadRepository<>)) .InstancePerLifetimeScope(); } }
Program.cs中的DbContext配置
var connectionString = builder.Configuration.GetConnectionString("SapScriptConnection"); var defaultConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<SapScriptDbContext>(cfg => cfg.UseSqlServer(connectionString)); builder.Services.AddDbContext<ApplicationDbContext>(cfg => cfg.UseSqlServer(defaultConnectionString));
异常堆栈跟踪
System.ArgumentException: Cannot create a DbSet for 'CooisHeader' because this type is not included in the model for the context.
at Cutter.Pages.IndexModel.OnGetDataAsync(String pro) in C:\Users\boksand-adm\source\repos\Cutter\Cutter\Pages\Index.cshtml.cs:line 95
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
已尝试的解决方式
- 使用Keyed注册管理多DbContext仓储,仍出现相同异常
- 目前仅能通过逐个注册实体对应的仓储解决问题,但希望采用泛型注册方式:
builder.RegisterType<SapScriptEfRepository<CooisHeader>>().As<IRepository<CooisHeader>>(); builder.RegisterType<SapScriptEfRepository<CooisComponent>>().As<IRepository<CooisComponent>>(); builder.RegisterType<AppEfRepository<Cut>>().As<IRepository<Cut>>();
内容的提问来源于stack exchange,提问作者Danijel Boksan

