То, что вы делаете, нехорошо и может определенно привести к проблемам. Поскольку это делается при регистрации службы, служба с заданной областью будет получать один раз при первом введении вашего синглтона. Другими словами, этот код здесь будет запускаться только один раз за время существования службы, которую вы регистрируете, что означает, что это будет происходить только один раз, точка. Кроме того, контекст, который вы здесь вводите, существует только в созданной вами области, которая исчезает, как только оператор using закрывается. Таким образом, к тому времени, когда вы действительно попытаетесь использовать контекст в своем синглтоне, он будет удален, и вы получите ObjectDisposedException
.
Если вам нужно использовать сервис с определенными областями внутри синглтона, то вам нужно внедрить IServiceProvider
в синглтон. Затем вам нужно создать область и вытащить свой контекст , когда вам нужно будет использовать его , и это нужно будет делать каждый раз, когда вам нужно его использовать. Например:
public class PersistedConfigurationService : IPersistedConfigurationService
{
private readonly IServiceProvider _serviceProvider;
public PersistedConfigurationService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task Foo()
{
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<IPersistedConfigurationDbContext>();
// do something with context
}
}
}
Просто чтобы подчеркнуть, опять же, вам нужно будет делать это в каждом методе, который должен использовать сервис с определенными областями (ваш контекст). Вы не можете сохранить это до ивара или чего-то еще. Если вы отстранены от кода, вы должны быть, так как это антипаттерн. Если вы должны получить услугу с заданной областью действия в одиночном разряде, у вас нет выбора, но чаще всего это признак плохого дизайна. Если сервису необходимо использовать сервисы с определенной областью, он почти всегда должен быть сам по себе, а не синглтоном. Есть только несколько случаев, когда вам действительно нужно время жизни синглтона, и те в основном вращаются вокруг работы с семафорами или другим состоянием, которое должно сохраняться в течение всего жизненного цикла приложения. Если у вас нет очень веских причин для того, чтобы сделать ваш сервис одноразовым, вы должны выбрать область действия во всех случаях; scoped должен быть временем жизни по умолчанию, если у вас нет причин поступать иначе.