Синглтон с 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, поскольку он по-прежнему настроен на данный момент.
Как избежать этой ошибки, когда мне нужен этот синглтон для запуска после запуска проекта?
Спасибо за вашу помощь.
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