C# 启动时,我应该如何在ConfigurationServices ASP.NET Core 2.0中使用appsettings.json配置键/值?

C# 启动时,我应该如何在ConfigurationServices ASP.NET Core 2.0中使用appsettings.json配置键/值?,c#,asp.net,asp.net-core,C#,Asp.net,Asp.net Core,我正在尝试为ASP.NET Core 2.0应用程序/网站配置服务 我希望在此方法中引用我的appsettings.json文件中的一些键/值 我不确定我要做的是否合适: public void ConfigureServices(IServiceCollection services) { services.AddMvcCore() .AddJsonFormatters() .AddCors(); var application

我正在尝试为ASP.NET Core 2.0应用程序/网站配置服务

我希望在此方法中引用我的
appsettings.json
文件中的一些键/值

我不确定我要做的是否合适:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore()
            .AddJsonFormatters()
            .AddCors();

    var applicationSettings = Configuration.GetSection("Settings").Get<ApplicationSettings>();
    services.AddSingleton(applicationSettings);

    // ** THIS IS WHAT I ORIGINALLY HAD, BUT IT'S ONLY SETTING
    //    THE VALUE IN DI/IOC.
    //services.Configure<ApplicationSettings>(options => Configuration.GetSection("Settings")
    //                                                                .Bind(options));

    var foo = new Foo(applicationSettings.SomeSetting);
    services.AddSingleton(foo);  
}
public void配置服务(IServiceCollection服务)
{
services.AddMvcCore()
.AddJsonFormatters()文件
.AddCors();
var applicationSettings=Configuration.GetSection(“设置”).Get();
服务。添加单例(应用程序设置);
//**这是我最初拥有的,但它只是一种设置
//以DI/IOC表示的值。
//services.Configure(选项=>Configuration.GetSection(“设置”)
//.绑定(选项));
var foo=新foo(applicationSettings.SomeSetting);
服务。添加单例(foo);
}
看看我是如何手动添加一个单例的,然后在以后引用appsettings实例中的值的

vs

只是配置

那么,这两种方法都可以吗?或者有具体的原因吗


请记住->我需要将我的设置注入控制器等等。

这种方法的问题是,不可能通过DI加载多个配置部分。配置API具有许多特性,例如可插拔配置、快照等。 我建议您至少使用一个类来绑定配置节,以便DI可以根据其类型注入它。如果您进一步需要另一个配置类,您将不会遇到问题


从技术上讲,您可以选择其中一种。在这两种情况下,您都通过依赖项注入注册了配置并使其可用,因此一切都可以依赖它,并将获得配置实例

您还在那里使用集中设置
配置
,因此您可以从那里的配置堆栈中获得所有好处,例如多个提供程序或特定于环境的覆盖

然而,用户肯定已经转向使用自定义配置的
IOptions
方式。这是“最先进的”技术,在整个ASP.NET核心中用于几乎所有内容。它还允许您切换到可以在运行时更新的选项。这是非常强大的,并且最终可能会变得有用(不一定适用于您和singleton的特定情况,但可能适用于其他情况)

这也很容易设置,实际上比您尝试的要短:

services.Configure<ApplicationSettings>(Configuration.GetSection("Settings"));

services.AddSingleton<Foo>();
与仅将委托传递给
AddJwtBearer()
相比,这可能显得不必要的冗长,但请注意,这正是传递该委托时在引擎盖下发生的情况:将创建一个
IConfigureOptions
对象,该对象在
Configure()
调用中调用您的委托。所以这其实是一样的

请注意,对于身份验证方案,实际上可能会设置一个
IConfigureNamedOptions
,这几乎是一样的,只是它可以基于名称配置选项。对于身份验证方案,这是方案名称,因此基本上您可以在
Configure()
中检查方案名称,然后决定如何配置选项


至于创建单例实例,特别是昂贵的实例,我认为
ConfigureServices
不适合这样做
ConfigureServices
在应用程序启动阶段很早就被调用,此时整个DI基础设施还不存在。因此,在创建实例时,您不能依赖任何东西。我还认为,创建对象仍然不是您的工作,但您应该DI处理对象的创建,并因此赋予它对其生命周期的控制权

如果您确实需要控制实例的创建时间,我建议您为此使用生命周期事件:基本上,在应用程序正确设置之后,但在第一个请求到来之前,您请求服务的实例并对其进行初始化。这样,您仍然可以让它完全依赖于DI,并且不会在第一个请求中延迟创建它

您可以在
Configure
方法中注册生命周期处理程序:

public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime)
{
    applicationLifetime.ApplicationStarted.Register(() =>
    {
        // application has started, request the singleton here to trigger DI to
        // create the instance
        app.ApplicationServices.GetService<ExpensiveSingleton>();
    });

    // …
}


}
public void配置(iaapplicationbuilder应用程序、iaapplicationlifetime applicationLifetime)
{
applicationLifetime.ApplicationStarted.Register(()=>
{
//应用程序已启动,请在此请求singleton以触发DI
//创建实例
app.ApplicationServices.GetService();
});
// …
}
}

Great answer@poke,但您能否添加/增强您将如何使用上述建议方法引用/使用
ConfigureServices
方法中的配置值。我可以看到您如何配置
应用程序设置
,但我仍然不确定如何在同一种特殊方法中配置和使用它。@Pure.Krome好吧,您只是不在配置服务中使用它。你想用它做什么?设置mu JWT选项。还有,我在
ConfigureServices
中创建存储(单例),然后传递该实例的db连接字符串(创建该实例的成本很高,因此建议在应用程序启动时进行…)@Pure.Krome我仍然不相信您应该在
ConfigureServices
中执行这两项操作。我已经扩展了我的答案来回应这些要求。感谢@Poke花时间帮助回答这个问题:)非常感谢!
// instead of passing an option configuration delegate here…
services.AddAuthentication().AddJwtBearer();

// … we register a IConfigureOptions<JwtBearerOptions> instead
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>();

// … ConfigureJwtBearerOptions could look like this:
class ConfigureJwtBearerOptions : IConfigureOptions<JwtBearerOptions>
{
    private readonly ApplicationSettings _settings;

    public ConfigureJwtBearerOptions(IOptions<ApplicationSettings> settings)
    {
        _settings = settings.Value;
    }

    public void Configure(JwtBearerOptions options)
    {
        // configure JwtBearerOptions here, and use your ApplicationSettings
        options.MetadataAddress = _settings.JwtMetadataAddress;
    }
}
public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime)
{
    applicationLifetime.ApplicationStarted.Register(() =>
    {
        // application has started, request the singleton here to trigger DI to
        // create the instance
        app.ApplicationServices.GetService<ExpensiveSingleton>();
    });

    // …
}


}