You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:37:00