In our web app dependency injection, we configure the ISearchIndexClient
instances returned by .NET Azure Search SDK's SearchServiceClient.Indexes.GetClient(...)
as a singletons.
We did this because of the answer https://stackoverflow.com/a/43502662 mentions that these classes share a single HTTP client. To avoid port exhaustion we want a single shared HttpClient
.
The problem with this, however, is that this means we need to restart the web app to cause the new query key (secret) to be reloaded from KeyVault. Consider a secret rotation flow: we need to restart/redeploy our web app after putting the new secret in KeyVault but before invalidating the old secret.
Is there a factory or another pattern the Azure Search .NET SDK recommends for periodically getting a new SearchServiceClient
or ISearchIndexClient
? I want a singleton most of the time for performance reasons but would like a new instance every couple of hours (for example).
Our code looks something like this right now. It uses Autofac but I think it gets the point across:
containerBuilder
.Register(c =>
{
var options = c.Resolve<IOptionsSnapshot<AzureSearchConfiguration>>();
return new SearchServiceClient(
options.Value.SearchServiceName,
new SearchCredentials(options.Value.SearchServiceApiKey));
});
containerBuilder
.Register(c =>
{
var serviceClient = c.Resolve<SearchServiceClient>();
var options = c.Resolve<IOptionsSnapshot<AzureSearchConfiguration>>();
return serviceClient.Indexes.GetClient(options.Value.SearchIndexName);
})
.SingleInstance();
I can build a time-based factory that spits out a new SearchServiceClient
or ISearchIndexClient
from time to time but I was hoping that something already existed.
Implementing your own factory/pool for SearchIndexClient
instances is the way to go. Unfortunately this kind of functionality isn't included in the SDK, so you'll have to roll your own.