Reputation: 393
I am using ASP.net core. I have problem with implementing dbcontext into singleton.
I need my singleton IModuleRepository to be running right after start of the project. So I am creating new instance of this dependency in public void ConfigureServices(IServiceCollection services)
in Startup.cs
file.
This singleton is using another singleton, so I am using it like this:
services.AddDbContext<ModulesDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableSensitiveDataLogging());
...
services.AddSingleton<IModuleRepository, ModuleRepository>();
services.AddSingleton<ICommunicationRepository>(new CommunicationRepository(services.BuildServiceProvider().GetService<IModuleRepository>()));
In ModuleRepository I am using DBcontext.
// Db context
private readonly ModulesDbContext _modulesDbContext;
public ModuleRepository(ModulesDbContext modulesDbContext)
{
_modulesDbContext = modulesDbContext;
}
When I am calling _modulesDbContext.SomeModel.ToList();
I get error:
System.InvalidOperationException: An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.
How to avoid this error when I need this singleton to run after the project is started?
Thank you for your help.
Upvotes: 3
Views: 2900
Reputation: 393
I figured out this problem. This calling of the dependencies were right. The error is that in CommunicationRepository I've created 2 Task and both of them were using the same DbContext - so it was using it multiple times. I had to say task.Wait();
Full code in constructor of the CommunicationRepository after correction:
// Add pernament communication
var task = new Task(AddPernamentCommunicationAll);
task.Start();
task.Wait();
// Add modules
var taskModules = new Task(AddModulesToList);
taskModules.Start();
Thank you for your answers.
Upvotes: -1
Reputation: 58863
As @Ilya Chumakov commented, you could just tell the DI container to use your concrete class like so:
services.AddSingleton<ICommunicationRepository, CommunicationRepository>();
Then any class can depend on ICommunicationRepository
and get the concrete repository, which gets the Db context.
Upvotes: 2