如何通过依赖注入DI启动引导CosmosDB客户端及使用方法
CosmosDB客户端引导与依赖注入使用指南
一、CosmosDB客户端的引导方式
1. 基础直接实例化(简单场景)
若无需依赖注入,可直接通过连接字符串构造客户端:
var connectionString = "你的CosmosDB连接字符串"; var cosmosClient = new CosmosClientBuilder(connectionString).Build();
但该方式不利于代码解耦与测试,推荐使用依赖注入方案。
2. 依赖注入方式(推荐)
你提供的代码已正确实现依赖注入注册,将CosmosClient注册为单例服务(符合官方最佳实践:CosmosClient是线程安全的,单例可最大化复用连接资源):
services.AddSingleton(s => { var connectionString = Configuration["CosmosDBConnection"]; if (string.IsNullOrEmpty(connectionString)) { throw new InvalidOperationException( "Please specify a valid CosmosDBConnection in the appSettings.json file or your Azure Functions Settings."); } return new CosmosClientBuilder(connectionString) .Build(); });
二、如何在代码中使用注入的CosmosDB客户端
1. 在ASP.NET Core控制器中使用
通过构造函数注入CosmosClient,直接在控制器方法中操作数据:
public class ProductsController : ControllerBase { private readonly CosmosClient _cosmosClient; // 构造函数注入CosmosClient实例 public ProductsController(CosmosClient cosmosClient) { _cosmosClient = cosmosClient; } [HttpGet] public async Task<IActionResult> GetAllProducts() { // 获取指定数据库和容器 var database = _cosmosClient.GetDatabase("YourDatabaseName"); var container = database.GetContainer("Products"); // 示例:执行查询并遍历结果 var queryIterator = container.GetItemQueryIterator<Product>("SELECT * FROM c"); var results = new List<Product>(); while (queryIterator.HasMoreResults) { var response = await queryIterator.ReadNextAsync(); results.AddRange(response.Resource); } return Ok(results); } }
2. 在自定义服务类中使用
将CosmosClient注入到自定义服务,封装数据操作逻辑:
public interface IProductService { Task<Product> GetProductById(string id); } public class ProductService : IProductService { private readonly Container _productContainer; public ProductService(CosmosClient cosmosClient) { // 提前初始化容器,避免重复调用GetDatabase/GetContainer var database = cosmosClient.GetDatabase("YourDatabaseName"); _productContainer = database.GetContainer("Products"); } public async Task<Product> GetProductById(string id) { try { // 根据ID和分区键读取数据(分区键需与容器配置一致) var response = await _productContainer.ReadItemAsync<Product>( id, new PartitionKey(id)); return response.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { return null; } } }
记得将自定义服务注册到DI容器:
services.AddScoped<IProductService, ProductService>();
3. 在Azure Functions中使用
无论是Isolated Worker还是In-Process模型,均支持构造函数注入:
public class GetProductFunction { private readonly CosmosClient _cosmosClient; public GetProductFunction(CosmosClient cosmosClient) { _cosmosClient = cosmosClient; } [FunctionName("GetProduct")] public async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "products/{id}")] HttpRequest req, string id) { var container = _cosmosClient.GetDatabase("YourDatabaseName").GetContainer("Products"); try { var product = await container.ReadItemAsync<Product>(id, new PartitionKey(id)); return new OkObjectResult(product.Resource); } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { return new NotFoundResult(); } } }
注意事项
CosmosClient是线程安全的,单例注册是最优方案,避免频繁创建实例带来的连接开销- 建议在服务初始化时提前获取
Database和Container实例,减少重复调用的性能损耗 - 务必处理
CosmosException,覆盖资源不存在、请求速率超限等常见异常场景
内容的提问来源于stack exchange,提问作者Alex Gordon
相关产品推荐
相关产品推荐

