Singleton with DbContext - instantiating in Startup.cs

I am using ASP.net core. I have a problem implementing dbcontext in singleton.

I need my singleton IModuleRepository to work right after starting the project. So I create a new instance of this dependency in a file public void ConfigureServices(IServiceCollection services)

in Startup.cs

.

This singleton is using another singleton, so I use 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 the ModuleRepository, I am using DBcontext.

// Db context
    private readonly ModulesDbContext _modulesDbContext;

    public ModuleRepository(ModulesDbContext modulesDbContext)
    {
        _modulesDbContext = modulesDbContext;
    }

      

When I call _modulesDbContext.SomeModel.ToList();

, I get an error:

System.InvalidOperationException: An attempt was made to use the context while configuring it. The DbContext instance cannot be used inside OnConfiguring because it is still configured at this point.

How can I avoid this error when I need this singleton to run after starting the project?

Thank you for your help.

+3


source to share


2 answers


I figured out this problem. This dependency requirement was correct. The error is that in CommunicationRepository I created 2 Tasks and they both used the same DbContext - so it used it multiple times. I should have saidtask.Wait();

Full code in CommunicationRepository constructor after fix:



// 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 responses.

-1


source


As @Ilya Chumakov commented, you can simply tell the DI container to use its specific class like this:

services.AddSingleton<ICommunicationRepository, CommunicationRepository>();

      



Then any class can depend on ICommunicationRepository

and get a specific repository that gets the Db context.

+2


source







All Articles