ASP. NET Core IO C: ASP0000 Вызов «BuildServiceProvider» из кода приложения приводит к созданию дополнительной копии одноэлементных сервисов. - PullRequest
2 голосов
/ 27 февраля 2020

Я работаю над. Net Базовое веб-приложение с IdentityServer4, установленным и настроенным на Startup.cs. Здесь я загружаю сертификат подписи токена из службы, которую я уже зарегистрировал в IO C:

        builder.AddSigningCredential(services.BuildServiceProvider().
        GetService<ISecretStoreService>().
        TokenSigningCertificate().Result);

Ниже полного кода:

public void ConfigureServices(IServiceCollection services)
{
    //....

        var builder = services.AddIdentityServer(options =>
            {
                options.IssuerUri = Configuration.GetValue<string>("IdSrv:IssuerUri"); ;
                options.PublicOrigin = Configuration.GetValue<string>("IdSrv:PublicOrigin"); ;
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
                options.UserInteraction.LoginUrl = "/Account/Login";
                options.UserInteraction.LogoutUrl = "/Account/Logout";
                options.Authentication = new AuthenticationOptions()
                {
                    CookieLifetime = TimeSpan.FromHours(10),
                    CookieSlidingExpiration = true
                };
            })
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
        })
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            options.EnableTokenCleanup = true;
        })
        .AddAspNetIdentity<AppUser>()
        .AddExtensionGrantValidator<PhoneNumberTokenGrantValidator>();

    if (Environment.IsDevelopment())
    {
        builder.AddDeveloperSigningCredential();
    }
    else
    {
        builder.AddSigningCredential(services.BuildServiceProvider().
            GetService<ISecretStoreService>().
            TokenSigningCertificate().Result);
    }

    //....    
}

Также:

    public interface ISecretStoreService
{
    Task<X509Certificate2> TokenValidationCertificate();
    Task<X509Certificate2> TokenSigningCertificate();
    Task<X509Certificate2> RetrieveCertificate(string certName);
    Task<X509Certificate2> RetrieveSecretAsCertificate(string certName);
}

Я получаю это предупреждение, и оно имеет смысл, поскольку указатель службы является анти-шаблоном:

ASP0000 Вызов «BuildServiceProvider» из кода приложения приводит к созданию дополнительной копии одноэлементных сервисов. Рассмотрим альтернативы, такие как сервисы внедрения зависимостей в качестве параметров для «Настройка».

Вопрос здесь в том, как можно избежать вызова services.BuildServiceProvider() внутри класса запуска 'ConfigureServices(IServiceCollection services){...} для следования правильному шаблону и чтобы избавиться от этого предупреждения?

Я прошел некоторые ответы на SO, но это было просто, чтобы избавиться от предупреждения, но все же внедрить весь Service Locator, который является анти-паттерном. Я бы сказал, что единственное решение - расширить промежуточное ПО для добавления спецификаций c logi c (опции промежуточного ПО), чтобы я мог вызывать его без необходимости создания services.BuildServiceProvider().

...