. net основной Startup.cs CreateScope или BuildServiceProvider - PullRequest
2 голосов
/ 18 июня 2020

Я просто создаю новый API и из нескольких проектов заметил, что я пытаюсь получить файлы Config внутри Startup.cs разными способами. Первый способ выглядит так:

var serviceProvider = services.BuildServiceProvider();
var config = serviceProvider.GetRequiredService<IIdentityServerConfig>();

, а второй - так:

var scope = services.BuildServiceProvider().CreateScope();
var config = scope.ServiceProvider.GetRequiredService<Auth0Config>();

Мой вопрос: какой из них правильный? Или все равно?


Вот пример:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(m => m.AddPolicy(CorsName, o => o.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
    services.AddLogging(Configuration, nameof(DataConfig));

    AddConfigs(services);
    AddSingletons(services);
    AddTransients(services);

    ConfigureStripe(services);

    AddDatabaseContexts(services);
    AddAuthentication(services);
    AddServices(services);

    services.AddMvc().AddFluentValidation(m => m.RegisterValidatorsFromAssemblyContaining<QuestionValidator>());
}

Метод AddConfigs выглядит так:

private void AddConfigs(IServiceCollection services)
{
    services.Configure<Auth0Config>(Configuration.GetSection(nameof(Auth0Config)));
    services.Configure<DataConfig>(Configuration.GetSection(nameof(DataConfig)));
    services.Configure<EvaluatorConfig>(Configuration.GetSection(nameof(EvaluatorConfig)));
    services.Configure<StripeConfig>(Configuration.GetSection(nameof(StripeConfig)));
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddSingleton(m => m.GetRequiredService<IOptions<Auth0Config>>().Value);
    services.AddSingleton(m => m.GetRequiredService<IOptions<DataConfig>>().Value);
    services.AddSingleton(m => m.GetRequiredService<IOptions<EvaluatorConfig>>().Value);
    services.AddSingleton(m => m.GetRequiredService<IOptions<StripeConfig>>().Value);
}

А потом вы можно увидеть, как я получаю конфигурацию для других служб (например, метод AddAuthentication:

private static void AddAuthentication(IServiceCollection services)
{
    var scope = services.BuildServiceProvider().CreateScope();
    var config = scope.ServiceProvider.GetRequiredService<Auth0Config>();

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer("Bearer", options =>
    {
        options.Authority = config.Authority;
        options.Audience = config.ApiAudience;
    });
}

1 Ответ

1 голос
/ 18 июня 2020

Во-первых, вам нужно добавить сервисы в контейнер DI. Обычный подход - сделать это в ConfigureServices из Startup (также это возможно в Program.cs)

Вам не нужно вызывать services.BuildServiceProvider(), если вам нужен экземпляр IIdentityServerConfig в методе ConfigureServices, потому что он у вас уже должен быть.

Если вам нужен экземпляр IIdentityServerConfig в методе Configure, просто передайте его как параметр, например:

public void Configure(IApplicationBuilder app, IIdentityServerConfig config)
{
}

или используйте app:

app.ApplicationServices.GetService<IIdentityServerConfig>();

, так что правильный способ - не создавать поставщика услуг в файле запуска

, но если вам это действительно нужно, я бы предпочел использовать его, если новый прицел не нужен (думаю, не нужен)

var serviceProvider = services.BuildServiceProvider();
var config = serviceProvider.GetRequiredService<IIdentityServerConfig>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...