Azure-docs: Info on how to use CosmosClient

Created on 4 Jun 2019  Â·  6Comments  Â·  Source: MicrosoftDocs/azure-docs

How to use CosmosClient based on below on the article?

        builder.Services.AddSingleton((s) => {
            return new CosmosClient(Environment.GetEnvironmentVariable("COSMOSDB_CONNECTIONSTRING"));
        });

Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Pri1 azure-functionsvc cxp product-question triaged

Most helpful comment

Hi @DixitArora-MSFT, sorry for resurrecting the issue.

The problem with injecting CosmosClient directly appears when we have multiple Cosmos DBs (different connection strings) to connect. Cosmonaut solves this by having a generic ICosmosStore<T> type allowing us to register a singleton client per data model and specify a different connection string for each.

It would be great if we could correlate a CosmosClient registration with a type (or maybe a name) like that, so we could be able to register multiple clients like:

```c#
// Typed:
services.AddCosmosClient(productDbConnectionString);
services.AddCosmosClient(userDbConnectionString);

// Named:
services.AddCosmosClient("products", productDbConnectionString);
services.AddCosmosClient("users", userDbConnectionString);


And resolve them like:

```c#
// Typed:
public ProductService(CosmosClient<ProductService> productDBClient) =>
    _productDBClient = productDBClient;

public UserService(CosmosClient<UserService> userDBClient) =>
    _userDBClient = userDBClient;

// Named:
public ProductService(CosmosClientFactory cosmosClients) =>
    _productDBClient = cosmosClients.Get("products");

public UserService(CosmosClientFactory cosmosClients) =>
    _userDBClient = cosmosClients.Get("users");

Is there a current best practice we can use to register multiple clients with the ability to resolve a specific one - maybe having a generic wrapper like the following and injecting that instead of naked clients?

```c#
public class CosmosClient
{
public CosmosClient(CosmosClient client) => Client = client;

public CosmosClient Client { get ; }

}
```

All 6 comments

@PingPongSet Thank you for your feedback! We will review and provide an update as appropriate.

@PingPongSet You can inject the CosmosClient directly.

There's an example of this in the Cosmos client samples directory which includes the following code:

private CosmosClient cosmosClient;

public AzureFunctionsCosmosClient(CosmosClient cosmosClient)
{
this.cosmosClient = cosmosClient;
}

What is the lifetime of CosmosClient, e.g. scoped, transient, or singleton? based on below:

builder.Services.AddSingleton((s) => {
string endpoint = configuration["EndPointUrl"];
if (string.IsNullOrEmpty(endpoint))
{
throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
}

            string authKey = configuration["AuthorizationKey"];
            if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
            {
                throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
            }

            CosmosClientBuilder configurationBuilder = new CosmosClientBuilder(endpoint, authKey);
            return configurationBuilder
                    .Build();
        });

https://github.com/MicrosoftDocs/azure-docs/issues/32679#issuecomment-498627791

@PingPongSet It should be Singleton.

@PingPongSet For now I will proceed with closure of this and If there are further questions regarding this matter, please tag me in your reply. We will gladly continue the discussion and we will reopen the issue.

Hi @DixitArora-MSFT, sorry for resurrecting the issue.

The problem with injecting CosmosClient directly appears when we have multiple Cosmos DBs (different connection strings) to connect. Cosmonaut solves this by having a generic ICosmosStore<T> type allowing us to register a singleton client per data model and specify a different connection string for each.

It would be great if we could correlate a CosmosClient registration with a type (or maybe a name) like that, so we could be able to register multiple clients like:

```c#
// Typed:
services.AddCosmosClient(productDbConnectionString);
services.AddCosmosClient(userDbConnectionString);

// Named:
services.AddCosmosClient("products", productDbConnectionString);
services.AddCosmosClient("users", userDbConnectionString);


And resolve them like:

```c#
// Typed:
public ProductService(CosmosClient<ProductService> productDBClient) =>
    _productDBClient = productDBClient;

public UserService(CosmosClient<UserService> userDBClient) =>
    _userDBClient = userDBClient;

// Named:
public ProductService(CosmosClientFactory cosmosClients) =>
    _productDBClient = cosmosClients.Get("products");

public UserService(CosmosClientFactory cosmosClients) =>
    _userDBClient = cosmosClients.Get("users");

Is there a current best practice we can use to register multiple clients with the ability to resolve a specific one - maybe having a generic wrapper like the following and injecting that instead of naked clients?

```c#
public class CosmosClient
{
public CosmosClient(CosmosClient client) => Client = client;

public CosmosClient Client { get ; }

}
```

Was this page helpful?
0 / 5 - 0 ratings