简体   繁体   English

如何使用异步方法在 DI 中创建 Cosmos 客户端?

[英]How to use async methods to create Cosmos Client in DI?

I want to use Cosmos DB in my ASP.net 5 WebAPI project.我想在我的 ASP.net 5 WebAPI 项目中使用 Cosmos DB。 To create the client I want to use Dependency injection to inject it to my Service.要创建客户端,我想使用依赖注入将其注入到我的服务中。 To do so I created this statement in my public void ConfigureServices(IServiceCollection services)为此,我在public void ConfigureServices(IServiceCollection services)中创建了此语句

services.AddSingleton(async s => {
    var dbConfig = Configuration.GetSection("Database");
    var conn = dbConfig["ConnectionString"];
    var dbName = dbConfig["DbName"];
    if (string.IsNullOrEmpty(conn))
    {
       throw new ConfigurationErrorsException();
    }
    var client = new CosmosClient(conn);
    await client.CreateDatabaseIfNotExistsAsync(dbName);
    return client;
});

But in this case I get an error in my service when I try to inject it via:但在这种情况下,当我尝试通过以下方式注入服务时,我的服务出现错误:

public ProductService(ILogger<ProductService> logger, CosmosClient client)
{
    this._client = client;
    _logger = logger;
}

Because my arrow function returns Task<CosmosClient> instead of CosmosClient .因为我的箭头 function 返回Task<CosmosClient>而不是CosmosClient But how can I change that therefore Database-creation methos is async and I have to use await?!但是我该如何改变,因此数据库创建方法是异步的,我必须使用等待?!

THanks谢谢

Microsoft's Dependency Injection does not support async . Microsoft 的依赖注入不支持async

I recommend having a separate "schema deployer" project that is run as part of your deployment (or locally to create databases on the emulator).我建议有一个单独的“模式部署程序”项目作为部署的一部分运行(或在本地运行以在模拟器上创建数据库)。 Then you can remove the CreateDatabaseIfNotExistsAsync call and inject CosmosClient .然后,您可以删除CreateDatabaseIfNotExistsAsync调用并注入CosmosClient

If you must use CreateDatabaseIfNotExistsAsync from within your application (and not during deployment), then you will need to inject an asynchronous factory :如果您必须在应用程序中(而不是在部署期间)使用CreateDatabaseIfNotExistsAsync ,那么您将需要注入一个异步工厂

public sealed class CosmosClientFactory
{
  private readonly Lazy<Task<CosmosClient>> _lazy;

  public CosmosClientFactory(Configuration configuration)
  {
    _lazy = new(async () =>
    {
      var dbConfig = configuration.GetSection("Database");
      var conn = dbConfig["ConnectionString"];
      var dbName = dbConfig["DbName"];
      if (string.IsNullOrEmpty(conn))
      {
       throw new ConfigurationErrorsException();
      }
      var client = new CosmosClient(conn);
      await client.CreateDatabaseIfNotExistsAsync(dbName);
      return client;
    });
  }

  public Task<CosmosClient> CreateAsync() => _lazy.Value;
}

Usage:用法:

private readonly CosmosClientFactory _clientFactory;
public ProductService(ILogger<ProductService> logger, CosmosClientFactory clientFactory)
{
  _clientFactory = clientFactory;
  _logger = logger;
}
public async Task DoSomethingAsync()
{
  var client = await _clientFactory.CreateAsync();
  await client.DoSomethingAsync();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM