Синглтон с DbContext-создание экземпляра при запуске.CS



Я использую ASP.net ядро. У меня есть проблема с реализацией dbcontext в синглтон.



Мне нужно, чтобы мой синглетный IModuleRepository работал сразу после запуска проекта. Поэтому я создаю новый экземпляр этой зависимости в файле public void ConfigureServices(IServiceCollection services) в файле Startup.cs.



Этот синглтон использует другой синглтон, поэтому я использую его следующим образом:



services.AddDbContext<ModulesDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableSensitiveDataLogging());
...
services.AddSingleton<IModuleRepository, ModuleRepository>();
services.AddSingleton<ICommunicationRepository>(new CommunicationRepository(services.BuildServiceProvider().GetService<IModuleRepository>()));


В ModuleRepository я использую DBcontext.



// Db context
private readonly ModulesDbContext _modulesDbContext;

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


Когда я вызываю _modulesDbContext.SomeModel.ToList();, я получаю ошибку:



Система

.InvalidOperationException: была предпринята попытка использовать контекст во время его настройки. Экземпляр DbContext, который не может быть использован внутри OnConfiguring, поскольку он по-прежнему настроен на данный момент.




Как избежать этой ошибки, когда мне нужен этот синглтон для запуска после запуска проекта?



Спасибо за вашу помощь.
594   2  

2 ответов:

Как прокомментировал @Ilya Chumakov, вы можете просто сказать контейнеру DI использовать ваш конкретный класс следующим образом:

services.AddSingleton<ICommunicationRepository, CommunicationRepository>();

Тогда любой класс может зависеть от ICommunicationRepository и получить конкретный репозиторий, который получает контекст БД.

Я понял эту проблему. Этот вызов зависимостей был правильным. Ошибка в том, что в CommunicationRepository я создал 2 задачи, и обе они использовали один и тот же DbContext - поэтому он использовал его несколько раз. Я должен был сказать task.Wait();

Полный код в конструкторе объекта Communication Repository после исправления:

// Add pernament communication
        var task = new Task(AddPernamentCommunicationAll);
        task.Start();
        task.Wait();

        // Add modules
        var taskModules = new Task(AddModulesToList);
        taskModules.Start();

Спасибо за ваши ответы.

Comments

    Ничего не найдено.