I have one c# project which is using libraries from Ardalis Specification , I need to work with two different DbContext. So, from Autofac side I need to register generics which will implement IRepository, IReadRepository .With my current code when I should use repository related to one SapScriptDbContext it is throwing me an error "System.ArgumentException: Cannot create a DbSet for 'CooisHeader' because this type is not included in the model for the context."
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>();
}
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();
//If I comment this bellow app is working and no error
builder.RegisterGeneric(typeof(AppEfRepository<>))
.As(typeof(IRepository<>))
.As(typeof(IReadRepository<>))
.InstancePerLifetimeScope();
}
}
From Program.cs
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));
I'm trying to resolve DI with autofac where I can use generic repository for multiple dbcontexts UPDATE StackTrace: 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)
I had also tried with Keyed to manage it, but still same issue. Only what I found as solution is to RegisterType for each entity, to be honest it is something what I do not like and prefer to do it. This at the moment it works:
builder.RegisterType<SapScriptEfRepository<CooisHeader>>().As<IRepository<CooisHeader>>();
builder.RegisterType<SapScriptEfRepository<CooisComponent>>().As<IRepository<CooisComponent>>();
builder.RegisterType<AppEfRepository<Cut>>().As<IRepository<Cut>>();
C:\Users\boksand-adm\source\repos\Cutter\Cutter\Pages\Index.cshtml.cs:line 95
) which should help you try to repro it in a simpler test on your system. The message sounds like something from EF, indicating you may not have all the EF stuff wired up right. But I don't use EF or "Ardalis Specification" or Razor Pages, so I can't provide an answer here based on the available info.