AzureKeyVaultConfigurationProvider CancellationTokenSource 已被处置

AzureKeyVaultConfigurationProvider CancellationTokenSource has been disposed

我目前正在使用 IConfigurationBuilder.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential()); 将 Azure Key Vault 机密添加到我的 dotnet 6 应用程序中。

每当我解析 var configuration = serviceProvider.GetRequiredService<IConfiguration>(); 的实例时,我都会得到一个 IConfiguration 版本,我可以使用它来跨提供程序访问所有密钥。

    public static T GetOptions<T>(this IServiceCollection services, string sectionName)
    where T : new()
    {
        using var serviceProvider = services.BuildServiceProvider();
        var configuration = serviceProvider.GetRequiredService<IConfiguration>();
        var section = configuration.GetSection(sectionName);
        var options = new T();
        section.Bind(options);

        return options;
    }

但是当我离开上述方法时,IConfiguration 的实例显然被处理掉了,我收到以下异常:

at System.ThrowHelper.ThrowObjectDisposedException(ExceptionResource resource) at System.Threading.CancellationTokenSource.Cancel()
at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose(Boolean disposing) at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose() at Microsoft.Extensions.Configuration.ConfigurationManager.DisposeRegistrationsAndProvidersUnsynchronized() at Microsoft.Extensions.Configuration.ConfigurationManager.Dispose()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose()

我假设 IConfiguration 是 IServiceCollection 中的单例,但为什么会被处置。为什么销毁对象时CancellationTokenSource为NULL?

but why is getting disposed then

您正在构建和处置整个服务提供者,这导致处置一切(实现 IDisposable 的内容)created/owned:

var services = new ServiceCollection();
services.AddSingleton<MyDisposable>(); 
// note that changing to services.AddSingleton(new MyDisposable()); will change behaviour of the program
var sp = services.BuildServiceProvider();
var myDisposable = sp.GetRequiredService<MyDisposable>();
sp.Dispose();
Console.WriteLine(myDisposable.Disposed); // prints True

public class MyDisposable : IDisposable
{
    public bool Disposed { get; set; }
    public void Dispose()
    {
        Disposed = true;
    }
}

一般来说,您应该避免多次构建 ServiceProvider,并且应该使用现有的 API 在需要的地方进行配置。但是如果没有其余的代码,就很难说出 GetOptions 应该如何 changed/refactoried.