Reputation: 8751
I have a dotnet core 3.1 C# XUnit Project.
It has a Startup class containing the following Initialise method:
public static IServiceProvider Initialise()
{
var services = new ServiceCollection();
ConfigureServices(services);
return services.BuildServiceProvider();
}
The ConfigureServices method contains the following:
private static void ConfigureServices(IServiceCollection services)
{
services.AddSharedConfiguration(_metadataTokens);
services.AddLogging();
services.AddTransient<IStructuredLogger>(x => new StructuredLogger(x.GetRequiredService<ILogger<PortfolioActivation>>()));
services.AddClientApi(_metadataTokens);
}
The AddClientApi is an extension method containing the following:
public static void AddClientApi(this IServiceCollection services, Dictionary<string, string> metadataTokens)
{
services.AddHttpClient(
LocalSettings.HttpClientTypes.BrewinAvaloqHttpClient, client =>
{
client.BaseAddress = new Uri(metadataTokens[LocalSettings.ServiceConfigurationKeys.ClientApiBaseAddress]);
client.DefaultRequestHeaders.Add(LocalSettings.HttpHeaderKeys.CacheControl, "no-cac
}
).AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(10)
},
onRetry: (outcome, timespan, retryAttempt, context) =>
{
//compile error here because I don't have structuredLogger
structuredLogger.LogInfo($"Failure on http request: {outcome}. This is retry attempt:[{retryAttempt}]");
}
));
}
My problem is in the onRety block, I'd like to make use of the "StructuredLogger" service that's been added to the IServiceCollection in the ConfigureServices method. I'm not sure how because at this point, the BuildServiceProvider method has not yet been called?
Upvotes: 3
Views: 1949
Reputation: 1694
You should be able extract your service from IServiceProvider
in the same fashion as you can do it here:
services.AddSingleton<MyClass>();
services.AddSingleton<MyClass2>(provider => provider.GetRequiredService<MyClass>());
As stated in this GitHub issue, .AddPolicyHandler()
can be used to get access to IServiceProvider
by doing:
services.AddHttpClient("...")
.AddPolicyHandler((serviceProvider, request) => HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(10)
},
onRetry: (outcome, timespan, retryAttempt, context) =>
{
serviceProvider.GetRequiredService<IStructuredLogger>()
.LogInfo($"Failure on http request: {outcome}. This is retry attempt:[{retryAttempt}]");
}
));
Upvotes: 1