.Net C# +自动化+ Azure密钥库安全客户端:'ContainerBuilder'不包含'AddSecretClient'的定义

5hcedyr0  于 2022-11-19  发布在  .NET
关注(0)|答案(1)|浏览(152)

我正在使用IoC和Autofac在项目中注册依赖项,但无法注册SecretClient。
自动面配置扩展:

public static class AutofacConfigurationExtensions
{
    public static void AddAutofac(this IHostBuilder builder)
    {
        builder.UseServiceProviderFactory(new AutofacServiceProviderFactory());

        builder.ConfigureContainer<ContainerBuilder>
        (
            (_, builder) =>
            {
                builder.RegisterAssemblyModules(typeof(AutofacConfigurationExtensions));
                builder.RegisterModule(new SharedAutofacModule());
            }
        );
    }
}

共享自动面模块:

using Autofac;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Azure;

public class SharedAutofacModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var uri = new Uri("keyVaultUrl");
        var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = "clientId" });

        //attempt 1
        builder.AddSecretClient<SecretClient>(uri).WithCredential(tokenCredential);
        //attempt 2
        builder.AddSecretClient<SecretClient>(_ => new(new Uri(keyVaultUrl), tokenCredential));
        //attempt 3
        builder.RegisterType<SecretClient>(_ => new(new Uri("keyVaultUrl"), "tokenCredential"));

        builder.RegisterType<MicrosoftGraphEmailService>().As<IMailMessageSender>();
        builder.RegisterType<AzureKeyVaultSecretManager>();
    }
}

在我的SharedAutofacModule中,我可以注册MicrosoftGraphEmailService和AzureKeyVaultSecretManager,没有任何问题,但是我尝试注册SecretClient的3次都没有成功,它们就是无法构建。前2次出现以下错误:
“ContainerBuilder”不包含“AddSecretClient”的定义,并且最佳扩展方法重载“SecretClientBuilderExtensions.AddSecretClient(SecretClient,Uri)”需要类型为“SecretClient”的接收器
而第三个它给出了以下错误:
'RegisterType'方法没有任何多载接受1个参数
如果我以传统的微软方式使用DI(如下面的代码),注册SecretClient没有问题,但我需要使用Autofac。
Program.cs:

var config = InitConfiguration();
var clientId = config["AzureKeyVault:ClientId"];
var keyVaultUrl = config["AzureKeyVault:KeyVaultUrl"];

if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(keyVaultUrl))
{
    var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = clientId });

    var builder = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(s => s.AddSingleton<SecretClient>(_ => new(new Uri(keyVaultUrl), tokenCredential)));

    builder.AddAutofac();
    var host = builder.Build();
    await host.RunAsync();
}

有什么帮助吗?

olhwl3o2

olhwl3o21#

下面是一个使用EgonsoftHU.Extensions.DependencyInjection.Autofac nuget包的示例。
我创建了一个新的ASP.NET核心应用程序:AzureKeyVaultSecretClientExample

AzureKeyVaultSecretClient范例.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
    <PackageReference Include="Azure.Identity" Version="1.8.0" />
    <PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.4.0" />
    <PackageReference Include="EgonsoftHU.Extensions.DependencyInjection.Autofac" Version="2.0.0" />
  </ItemGroup>

</Project>

程序.cs

using System;

using Autofac;
using Autofac.Extensions.DependencyInjection;

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

using EgonsoftHU.Extensions.DependencyInjection;

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder
    .Host
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(
        (hostBuilderContext, containerBuilder) =>
        {
            containerBuilder
                // Discover all assemblies starting with the specified names.
                .UseDefaultAssemblyRegistry(
                    nameof(AzureKeyVaultSecretClientExample),
                    nameof(EgonsoftHU)
                )
                // Enables injection for Autofac modules.
                .TreatModulesAsServices()
                // It will inject the IConfiguration instance
                // into Autofac modules using property injection.
                .RegisterModuleDependencyInstance(
                    hostBuilderContext.Configuration
                )
                // Register the EgonsoftHU Autofac module
                // that will discover and register
                // all other Autofac modules.
                .RegisterModule<DependencyModule>();
        }
    );

// Add services to the container.
builder
    .Services
    .AddControllers()
    .AddControllersAsServices();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseAuthorization();
app.MapControllers();
app.Run();

public class AzureDependencyModule : Module
{
    // It will be automatically injected.
    public IConfiguration Configuration { get; set; } = default!;

    protected override void Load(ContainerBuilder builder)
    {
        var clientId = Configuration["AzureKeyVault:ClientId"];
        var keyVaultUrl = Configuration["AzureKeyVault:KeyVaultUrl"];

        var tokenCredential =
            new DefaultAzureCredential(
                new DefaultAzureCredentialOptions()
                {
                    ManagedIdentityClientId = clientId
                }
            );

        // Register a factory delegate.
        builder.Register<SecretClient>(
            context =>
            new(new Uri(keyVaultUrl), tokenCredential)
        );
    }
}

请注意:.RegisterModuleDependencyInstance<T>(T instance)方法使用一个临时的、单独的Autofac容器,专用于Autofac模块。

了解更多关于此nuget软件包的信息。

相关问题