C# 启动时,我应该如何在ConfigurationServices ASP.NET Core 2.0中使用appsettings.json配置键/值?
我正在尝试为ASP.NET Core 2.0应用程序/网站配置服务 我希望在此方法中引用我的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
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>();
});
// …
}
}