简体   繁体   中英

.net core Startup.cs CreateScope or BuildServiceProvider

I am just creating a new API and I have noticed from a couple of projects that I try to get Config files inside Startup.cs in different ways. The first way is like this:

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

and the second way is like this:

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

My question is, which one is right? Or does it not matter?


Here is an example:

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>());
}

The AddConfigs method looks like this:

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

And then you can see how I get a config for other services (for example the AddAuthentication method:

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

First, you need to add services to DI container. The common approach is to do that in ConfigureServices from Startup (also it is possible in Program.cs)

You don't need to call services.BuildServiceProvider() if you need an instance of IIdentityServerConfig in ConfigureServices method because you should already have it.

If you need the instance of IIdentityServerConfig in Configure method, then just pass it as a parameter like:

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

or use app :

app.ApplicationServices.GetService<IIdentityServerConfig>();

so, the right way is not building service provider in Startup file

but if you really need this, I would prefer to use this one if you don't need a new scope (I think you don't need)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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