C#多环境CosmosDB依赖注入:预加载全量资源信息遇阻求助
C#依赖注入预加载多环境CosmosDB信息问题
问题描述
我是C#新手,正在尝试在Program.cs中实现依赖注入。现有代码已实现ICosmosClientFactory工厂类,可根据指定环境创建对应的CosmosClient实例,运行正常。但我的需求是在应用启动阶段,通过Program.cs的依赖注入机制,预加载所有环境下CosmosDB的完整信息(包含账户、数据库及容器详情),并能直接使用这些信息。我尝试了两种注入方式,但均未能成功获取所需信息,具体代码如下:
现有可正常运行代码
Program.cs
builder.Services.AddSingleton<ICosmosClientFactory, CosmosClientFactory>();
ICosmosClientFactory.cs
using System; using Microsoft.Azure.Cosmos; using Newtonsoft.Json.Linq; namespace TestApplication.Interfaces { public interface ICosmosClientFactory { CosmosClient CreateClient(string environment); } }
CosmosClientFactory.cs
using System; using Microsoft.Azure.Cosmos; using System.Net; using MSaaSPartnerOnboarding.Interfaces; using Newtonsoft.Json.Linq; using Azure.Identity; namespace TestApplication.Models { public class CosmosClientFactory : ICosmosClientFactory { private readonly IConfiguration _configuration; public CosmosClientFactory(IConfiguration configuration) { _configuration = configuration; } /// <summary> /// 使用指定环境的配置和Azure托管标识认证,创建并配置<see cref="CosmosClient"/>类的新实例。 /// </summary> /// <param name="environment">环境名称,用于从配置中获取CosmosDB设置。</param> /// <returns>已配置的<see cref="CosmosClient"/>实例。</returns> /// <remarks> /// 方法会根据指定环境从应用配置中读取CosmosDB设置,使用带用户分配托管标识的<see cref="DefaultAzureCredential"/>进行认证。 /// CosmosClientOptions配置了特定的连接模式、端口复用模式和重试策略。 /// </remarks> public CosmosClient CreateClient(string environment) { var cosmosDbSettings = _configuration.GetSection(environment).GetChildren() .ToDictionary(section => section.Key, section => section.Value); var cosmosClientOptions = new CosmosClientOptions { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(_configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = _configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(_configuration.GetValue<int>("RequestTimeout")) }; var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = cosmosDbSettings["UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); var cosmosDBAccountName = cosmosDbSettings["CosmosDBAccountName"]; return new CosmosClient($"https://{cosmosDBAccountName}.documents.azure.com:443/", tokenCredential, cosmosClientOptions); } } }
尝试的两种依赖注入方式
方式一
static void CreateClient(WebApplicationBuilder builder) { var environments = new[] { "WWPPE", "WWProd", "EUPPE", "EUProd" }; foreach (var environment in environments) { builder.Services.AddSingleton<CosmosClient>(provider => { var configuration = provider.GetRequiredService<IConfiguration>(); var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = configuration[$"{environment}:UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); var options = new CosmosClientOptions { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(configuration.GetValue<int>("RequestTimeout")) }; var cosmosDBAccountName = configuration[$"{environment}:CosmosDBAccountName"]; var agentViewCosmos = configuration[$"{environment}:BaseUrl"]; return new CosmosClient(agentViewCosmos, tokenCredential, options); }); } }
方式二
static void AddCosmos(WebApplicationBuilder builder) { builder.Services.AddAzureClients(factoryBuilder => { // 使用MyApplicationOptions注册客户端以获取构造参数 factoryBuilder.AddClient<CosmosClient, CosmosClientOptions>((options, credential, provider) => { var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = builder.Configuration["dev:UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(_configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = _configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(_configuration.GetValue<int>("RequestTimeout")) }; var agentViewCosmos = builder.Configuration["dev:BaseUrl"]; return new CosmosClient(agentViewCosmos, credential, options); }).WithCredential(tokenCredential) .WithName("dev"); factoryBuilder.AddClient<CosmosClient, CosmosClientOptions>((options, credential, provider) => { var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = builder.Configuration["test:UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(_configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = _configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(_configuration.GetValue<int>("RequestTimeout")) }; var agentViewCosmos = builder.Configuration["test:BaseUrl"]; return new CosmosClient(agentViewCosmos, credential, options); }).WithCredential(tokenCredential) .WithName("test"); factoryBuilder.AddClient<CosmosClient, CosmosClientOptions>((options, credential, provider) => { var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = builder.Configuration["PreProd:UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(_configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = _configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(_configuration.GetValue<int>("RequestTimeout")) }; var agentViewCosmos = builder.Configuration["PreProd:BaseUrl"]; return new CosmosClient(agentViewCosmos, credential, options); }).WithCredential(tokenCredential) .WithName("PreProd"); factoryBuilder.AddClient<CosmosClient, CosmosClientOptions>((options, credential, provider) => { var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = builder.Configuration["Prod:UserAssignedManagedIdentity"], ExcludeInteractiveBrowserCredential = true, ExcludeVisualStudioCodeCredential = true, ExcludeAzureCliCredential = true }); CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() { ConnectionMode = ConnectionMode.Direct, PortReuseMode = PortReuseMode.PrivatePortPool, EnableContentResponseOnWrite = false, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(_configuration.GetValue<int>("MaxRetryWaitTime")), MaxRetryAttemptsOnRateLimitedRequests = _configuration.GetValue<int>("MaxRetryAttempts"), RequestTimeout = TimeSpan.FromMinutes(_configuration.GetValue<int>("RequestTimeout")) }; var agentViewCosmos = builder.Configuration["Prod:BaseUrl"]; return new CosmosClient(agentViewCosmos, credential, options); }).WithCredential(tokenCredential) .WithName("Prod"); }); }
内容的提问来源于stack exchange,提问作者Diwakar Reddy
相关产品推荐
相关产品推荐

