Tengo un proyecto Web Api que depende en gran medida de Azure Cosmos DB. Hasta ahora, bastaba con tener una cuenta de Cosmos DB (una cadena de conexión). Ahora, un nuevo requisito es poder conectarse a un Cosmos diferente (dos cadenas de conexión) según un parámetro entrante.
Para el ID de cliente X, debemos obtener documentos de Cosmos DB 1 y para otro cliente Y debemos buscar en Cosmos DB 2.
Hasta ahora, mi archivo Startup.cs registraba una instancia única de CosmosClient. Que a su vez se instancia como este cosmosClient = new CosmosClient(endpointUrl, primaryKey); Y esto funcionó muy bien. La Web Api pudo procesar fácilmente todas las solicitudes. Pero ahora que tenemos que actualizar un CosmosClient por solicitud, el rendimiento es realmente malo.
Entonces mi pregunta es; ¿Hay alguna manera de tener múltiples instancias del mismo singleton? Como en; ¿Podemos crear una única instancia de la combinación Class+EndPointUrl? (¿Sería eso todavía un singleton?)
En este momento, estamos actualizando miles de CosmosClients cada minuto. Y realmente necesitamos uno más en comparación con lo que teníamos antes.
Hay varias formas de hacer esto, pero una implementación fácil sería crear un contenedor alrededor de cada CosmosClient que use. El único uso del contenedor será permitirle usar varias instancias de CosmosClient y diferenciarlas por sus tipos.
//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(...));Luego, en su lógica comercial, puede agregar ambos clientes y, según su lógica, elegir qué cliente desea usar:
public class MyService { public MyService(ContosoCosmosClient contosoClient, FabrikamCosmosClient fabrikamClient) { //... } }Gracias por todos los comentarios y respuestas.
Al final, en este caso, la mejor solución fue el enfoque sugerido por el Sr. T. https://devblogs.microsoft.com/cosmosdb/httpclientfactory-cosmos-db-net-sdk/
Ahora sigo usando un CosmosClient, Scoped. Lo que permite el uso dinámico de puntos finales.
Al inyectar IHttpClientFactory y configurar CosmosClientOptions de esta manera;
{ HttpClientFactory = () => _httpClientFactory.CreateClient("cosmos") });ahora estamos haciendo un uso completo de HttpClient y su capacidad para reutilizar puertos.