Хостинг-сервис - это одноэлементный, что означает, что для жизни приложения существует только один экземпляр этого класса.
Контекст ограничен, то есть имеет очень короткий срок службы (только дляконкретная «область действия», например один HTTP-запрос).Неполно оставаться в живых бесконечно (например, задействованы соединения БД, которые, как вы можете гарантировать, не будут оставаться открытыми на протяжении всего жизненного цикла приложения).
Если вы вставляете контекст в другой класс,Контекст будет существовать всю жизнь экземпляра этого класса.Для одноэлементного класса это жизнь приложения.Вот почему вы получаете исключение, которое вы делаете..NET Core говорит вам: «Это не сработает так, как вы думаете, сработает»
Решение здесь: https://stackoverflow.com/a/48368934/1202807
Короче, введите IServiceScopeFactory
, что дает вам возможность попросить механизм DI предоставить вам класс с областью видимости, когда это необходимо, и тогда вы можете удерживать его на уровне только столько, сколько вам нужно .
private readonly IServiceScopeFactory _scopeFactory;
public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
{
_logger = logger;
_scopeFactory = scopeFactory;
}
Тогда вы получите свой контекст следующим образом:
using (var scope = scopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<Context>();
//do what you need
}//scope (and context) gets destroyed here
Старый ответ (который здесь неправильный, но относится к другим типам классов):
Просто поместите его в конструктор, и он будет вставлен внедрением зависимостей :
public TimedHostedService(ILogger<TimedHostedService> logger, Context context)
{
_logger = logger;
_context = context;
}
Это строки services.AddDbContext()
, которые делают их доступными для внедрения зависимостей.Просто выберите нужный тип, так как вы определили два:
services.AddDbContext<Context>(options =>
options.UseSqlServer(Configuration.GetConnectionString("LaprDB")));
services.AddDbContext<ContextUsers>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection")));