依赖注入和连接字符串/单例的多个实例

Dependency Injection & connection strings / Multiple instances of a singleton

我有一个严重依赖 Azure Cosmos DB 的 Web Api 项目。到目前为止,拥有一个 Cosmos DB 帐户(一个连接字符串)就足够了。现在一个新的要求是能够根据传入的参数连接到不同的 Cosmos(两个连接字符串)。

对于客户 ID X,我们应该从 Cosmos DB 1 中获取文档,对于另一个客户 Y,我们必须在 Cosmos DB 2 中查找。

到目前为止,我的 Startup.cs 文件注册了 CosmosClient 的单例实例。依次像这样实例化 cosmosClient = new CosmosClient(endpointUrl, primaryKey); 这非常有效。 Web Api 能够轻松处理所有请求。但是现在我们必须为每个请求新建一个 CosmosClient,性能真的很差。

所以我的问题是;有没有办法拥有同一个单例的多个实例?如;我们可以创建组合 Class+EndPointUrl 的单个实例吗? (那还是单例吗?)

现在,我们每分钟都在更新数千个 CosmosClient。与我们之前拥有的相比,我们真的只需要一个。

有多种方法可以做到这一点,但一个简单的实现是围绕您使用的每个 CosmosClient 创建一个包装器。包装器的唯一用途是允许您使用 CosmosClient 的各种实例并按类型区分它们。

//Create your own class for each client inheriting the behaviour of CosmosClient
public class ContosoCosmosClient : CosmosClient
{
    public ContosoCosmosClient(string connectionString, CosmosClientOptions clientOptions = null) : base(connectionString, clientOptions)
    {
    }

    public ContosoCosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions = null) : base(accountEndpoint, authKeyOrResourceToken, clientOptions)
    {
    }

    public ContosoCosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions = null) : base(accountEndpoint, tokenCredential, clientOptions)
    {
    }
}
//In Startup.up add a Singleton for each client
services.AddSingleton(new ContosoCosmosClient(...));
services.AddSingleton(new FabrikamCosmosClient(...));

然后在您的业务逻辑中,您可以添加两个客户端,并根据您的逻辑选择要使用的客户端:

public class MyService
{
    public MyService(ContosoCosmosClient contosoClient, FabrikamCosmosClient fabrikamClient)
    {
        //...
    }
}

感谢所有评论和回答。

最后,是不是这种情况,最好的解决方案就是T老师建议的方法https://devblogs.microsoft.com/cosmosdb/httpclientfactory-cosmos-db-net-sdk/

我现在还在使用一个 CosmosClient,Scoped。这允许动态使用端点。

通过注入 IHttpClientFactory 并像这样设置 CosmosClientOptions;

  {
      HttpClientFactory = () => _httpClientFactory.CreateClient("cosmos")
  });

我们现在正在充分利用 HttpClient 及其重用端口的能力。