简体   繁体   English

在调用 BuildServiceProvider 之前将 dotnet 核心依赖注入到扩展方法

[英]dotnet core dependency injection to extension method before BuildServiceProvider is called

I have a dotnet core 3.1 C# XUnit Project.我有一个 dotnet core 3.1 C# XUnit 项目。

It has a Startup class containing the following Initialise method:它有一个包含以下 Initialise 方法的 Startup 类:

public static IServiceProvider Initialise()
    {
        var services = new ServiceCollection();
        ConfigureServices(services);
        return services.BuildServiceProvider();
    }

The ConfigureServices method contains the following: ConfigureServices 方法包含以下内容:

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: AddClientApi 是一个扩展方法,包含以下内容:

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.我的问题是在 onRety 块中,我想利用在 ConfigureServices 方法中添加到 IServiceCollection 的“StructuredLogger”服务。 I'm not sure how because at this point, the BuildServiceProvider method has not yet been called?我不确定如何,因为此时尚未调用 BuildServiceProvider 方法?

You should be able extract your service from IServiceProvider in the same fashion as you can do it here:您应该能够以与您在此处执行的操作相同的方式从IServiceProvider中提取您的服务:

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:如此 GitHub 问题中所述.AddPolicyHandler()可用于通过执行以下操作来访问IServiceProvider

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}]");
    }
));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM