通常在 .NET Core 项目中,我会创建一个“boostrap”类来配置我的服务以及 DI 注册命令。这通常是 IServiceCollection
的扩展方法我可以在其中调用类似 .AddCosmosDbService
的方法并且所有必要的东西都是包含该方法的静态类中的“独立”。但关键是该方法获得 IConfiguration
来自Startup
类。
我过去曾在 Azure Functions 中使用过 DI,但尚未遇到此特定要求。
我正在使用IConfiguration
绑定(bind)到一个具体类,其属性与我的 local.settings.json
中的设置相匹配以及在 Azure 中部署该函数时的开发/生产应用程序设置。
CosmosDbClientSettings.cs
/// <summary>
/// Holds configuration settings from local.settings.json or application configuration
/// </summary>
public class CosmosDbClientSettings
{
public string CosmosDbDatabaseName { get; set; }
public string CosmosDbCollectionName { get; set; }
public string CosmosDbAccount { get; set; }
public string CosmosDbKey { get; set; }
}
BootstrapCosmosDbClient.cs
public static class BootstrapCosmosDbClient
{
/// <summary>
/// Adds a singleton reference for the CosmosDbService with settings obtained by injecting IConfiguration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static async Task<CosmosDbService> AddCosmosDbServiceAsync(
this IServiceCollection services,
IConfiguration configuration)
{
CosmosDbClientSettings cosmosDbClientSettings = new CosmosDbClientSettings();
configuration.Bind(nameof(CosmosDbClientSettings), cosmosDbClientSettings);
CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbClientSettings.CosmosDbAccount, cosmosDbClientSettings.CosmosDbKey);
CosmosClient client = clientBuilder.WithConnectionModeDirect().Build();
CosmosDbService cosmosDbService = new CosmosDbService(client, cosmosDbClientSettings.CosmosDbDatabaseName, cosmosDbClientSettings.CosmosDbCollectionName);
DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(cosmosDbClientSettings.CosmosDbDatabaseName);
await database.Database.CreateContainerIfNotExistsAsync(cosmosDbClientSettings.CosmosDbCollectionName, "/id");
services.AddSingleton<ICosmosDbService>(cosmosDbService);
return cosmosDbService;
}
}
启动.cs
public class Startup : FunctionsStartup
{
public override async void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
await builder.Services.AddCosmosDbServiceAsync(**need IConfiguration reference**); <--where do I get IConfiguration?
}
}
显然为 IConfiguration
添加了一个私有(private)字段在Startup.cs
不会工作,因为它需要填充一些东西,我也读过 using DI for IConfiguration
isn't a good idea .
我还尝试使用 here 中描述的选项模式并按如下方式实现:
builder.Services.AddOptions<CosmosDbClientSettings>()
.Configure<IConfiguration>((settings, configuration) => configuration.Bind(settings));
虽然这可以注入(inject) IOptions<CosmosDbClientSettings>
对于非静态类,我使用静态类来保存我的配置工作。
关于如何完成这项工作或可能的解决方法有什么建议吗?我更愿意将所有配置保留在一处(引导文件)。
最佳答案
自 Microsoft.Azure.Functions.Extensions 的版本 1.1.0 起您可以执行以下操作:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var configuration = builder.GetContext().Configuration;
builder.Services.AddCosmosDbService(configuration);
}
}
不幸的是,它仍然不支持异步配置,因此您仍然必须阻止等待任务完成或使用@Nkosi的答案中描述的技巧。
关于c# - 配置服务时如何通过依赖注入(inject)在 Azure Function V3 中注入(inject)或使用 IConfiguration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59474070/