【发布时间】:2020-04-15 20:22:45
【问题描述】:
通常在 .NET Core 项目中,我会创建一个“boostrap”类来配置我的服务以及 DI 注册命令。这通常是IServiceCollection 的扩展方法,我可以在其中调用.AddCosmosDbService 之类的方法,并且在包含该方法的静态类中,所有必要的东西都是“自包含的”。但关键是该方法从 Startup 类中获取了一个 IConfiguration。
我过去曾在 Azure Functions 中使用 DI,但尚未遇到此特定要求。
当函数部署在 Azure 中时,我正在使用 IConfiguration 绑定到具有与我的 local.settings.json 以及开发/生产应用程序设置匹配的属性设置的具体类。
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;
}
}
Startup.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?
}
}
显然在Startup.cs 中为IConfiguration 添加一个私有字段是行不通的,因为它需要填充一些东西,而且我也读过using DI for IConfiguration isn't a good idea。
我也尝试过使用here 中描述的选项模式并按如下方式实现:
builder.Services.AddOptions<CosmosDbClientSettings>()
.Configure<IConfiguration>((settings, configuration) => configuration.Bind(settings));
虽然这可以将IOptions<CosmosDbClientSettings> 注入非静态类,但我使用静态类来保存我的配置工作。
关于如何使这项工作或可能的解决方法有什么建议吗?我希望将所有配置保存在一个地方(引导文件)。
【问题讨论】:
-
看看@Casper 的回答。这不是最合适的吗?
标签: c# dependency-injection azure-functions .net-core-configuration