【问题标题】:AzureKeyVaultConfigurationProvider CancellationTokenSource has been disposedAzureKeyVaultConfigurationProvider CancellationTokenSource 已被释放
【发布时间】:2021-12-17 12:10:38
【问题描述】:

我目前正在使用 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 的实例显然被释放了,我收到以下异常:

在 System.ThrowHelper.ThrowObjectDisposedException(异常资源 资源)在 System.Threading.CancellationTokenSource.Cancel()
在 Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose(布尔 处置)在 Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose() 在 Microsoft.Extensions.Configuration.ConfigurationManager.DisposeRegistrationsAndProvidersUnsynchronized() 在 Microsoft.Extensions.Configuration.ConfigurationManager.Dispose()
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() 在 Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose()

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

【问题讨论】:

    标签: c# .net asp.net-core-mvc azure-keyvault .net-6.0


    【解决方案1】:

    但是为什么会被处理掉

    您正在构建和处置整个服务提供商,这会导致处置由它创建/拥有的所有内容(实现 IDisposable):

    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

    【讨论】:

      猜你喜欢
      • 2016-10-26
      • 2016-05-27
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多