ASP.NET Coreでの構成
12778 ワード
前言
我々の開発過程において、ASP.NETの構成は
ASP.NET CoreのWeb.configは既に存在しません(ただしIISに管理されている場合はweb.configを使用してIISを構成できます)、
appsettingsでjsonとappsettings.(Development、Staging、Production).jsonプロファイル
(ASP.NETにおけるWeb.configとWeb.Release.configの関係と理解できる).
次にASPを見てみましょう.NET Coreでの構成
基本的な使い方
結果を返します.
次の点に注意してください.キーは大文字と小文字を区別しません.たとえば、ConnectionsStringとconnectionstringは等価キーとみなされます. キー名が同じ(すべてのロードされたプロファイルを含む)場合は、最後の値に準じます.したがって、 マルチレベルは を参照する.上のような表記はキャッシュされていない、すなわち、 に変更される.
オブジェクトにバインドIOptionsまずJSONオブジェクトをオブジェクト に変換する. の結果を返します.
検出 になる必要はありません.ルートノードが オブジェクトにバインドされたOptionsSnapshotは . IOptionsSnapshotはIOptionsよりも多くの方法 である. IOptionsSnapshotはIOptionsを継承しています(ここで疑問ですが、上の
カスタムプロファイル(JSON)
時々配置情報が多く、個別のファイルに配置したい、ASP.NET Coreは、INI、XML、JSONファイルシステムのロード構成方法を提供します.まずProgram.csの settingを作成する.json: Controller: カスタムプロファイル(JSON)オブジェクトへのバインド
上記の構成により、取得構成がコンフィギュレーションオブジェクトSettingsクラス を定義するはStartupです.csの .用法上同様 何か見つけたか?jsonのプロファイルの情報も_に保存されます.configurationでは、ファイルが多くなるとノードが上書きされる可能性が高いので、書き方を変えます.まずProgramを削除する.csにおける プロファイルsettingを変更する.json: 在中Startup.csの これにより、グローバルな構成情報に影響を与えることはありません.
その他の方法次の2つの方法を見てみましょう. IOptionsMonitor、IOptionsFactory、IOptionsMonitor Cache方式:次のコード がトリガーされます.
最後に書く
我々の開発過程において、ASP.NETの構成は
Web.config
にある.JSON、XML、データベースなどに配置することもできます(ただし、ASP.NETは対応するモジュールや方法を提供していません).ASP.NET CoreのWeb.configは既に存在しません(ただしIISに管理されている場合はweb.configを使用してIISを構成できます)、
appsettingsでjsonとappsettings.(Development、Staging、Production).jsonプロファイル
(ASP.NETにおけるWeb.configとWeb.Release.configの関係と理解できる).
次にASPを見てみましょう.NET Coreでの構成
基本的な使い方
HomeController.cs
: [ApiController]
public class HomeController : ControllerBase
{
private readonly IConfiguration _configuration;
public HomeController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet("/")]
public dynamic Index()
{
return JsonConvert.SerializeObject(new
{
ConnectionString = _configuration["ConnectionString"],
Child1 = _configuration["Parent:Child1"],
Grandchildren = _configuration["Parent:Child2:Grandchildren"]
});
}
}
結果を返します.
{
"ConnectionString": "data source=.;initial catalog=TEST;user id=sa",
"Child1": "child",
"Grandchildren": "grandchildren"
}
appsettings.json
の値に対応:{
"ConnectionString": "data source=.;initial catalog=TEST;user id=sa;password=123",
"Parent": {
"Child1": "child1",
"Child2": "child2"
}
}
次の点に注意してください.
appsettings.(Development、Staging、Production).json
は、appsettings.json
の構成情報を上書きする.:
で分割するが、環境変数の場合、プラットフォーム間で問題が発生する詳細はappsettings.json
が修正すると、取得した値は直ちにオブジェクトにバインドIOptions
_configuration["Parent:Child2:Grandchildren"]
の書き方はプログラマーにとって反感を持っているに違いありません.次に、プロファイルをオブジェクトにバインドします.public class TestOptions
{
public string ConnectionString { get; set; }
public Parent Parent { get; set; }
}
public class Parent
{
public string Child1 { get; set; }
public Child2 Child2 { get; set; }
}
public class Child2
{
public string GrandChildren { get; set; }
}
Startup.cs
のConfigureServices
メソッドにコードを追加する:services.Configure(Configuration);
HomeController.cs
:[ApiController]
public class HomeController : ControllerBase
{
private readonly IOptions _options;
public HomeController(IOptions options)
{
_options = options;
}
[HttpGet("options")]
public string Options()
{
return JsonConvert.SerializeObject(_options);
}
}
は、{
"Value": {
"ConnectionString": "data source=.;initial catalog=TEST;user id=sa",
"Parent": {
"Child1": "child",
"Child2": {
"GrandChildren": "grandchildren"
}
}
}
}
検出
appsettings.json
を変更してページをリフレッシュすると、値はValue
であることを発見しました上の2つの問題に基づいてソースコードを見に行きます:まずこの文を見つけます:services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
OptionsManager
方法を見に行きます:public class OptionsManager : IOptions, IOptionsSnapshot where TOptions : class, new()
{
private readonly IOptionsFactory _factory;
// : _cache ConcurrentDictionary>()
// , Singleton ,
private readonly OptionsCache _cache = new OptionsCache();
public OptionsManager(IOptionsFactory factory)
{
_factory = factory;
}
///
/// TOptions
/// Value
///
public TOptions Value
{
get
{
return Get(Options.DefaultName);
}
}
///
/// IOptionsSnapshot
///
public virtual TOptions Get(string name)
{
name = name ?? Options.DefaultName;
// Store the options in our instance cache
return _cache.GetOrAdd(name, () => _factory.Create(name));
}
}
IOptions
の用法と同様に,注入に依存するライフサイクルがScopedであるためキャッシュされず,コードを直接見る:services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
TOptions Get(string name);
Value
属性が実際にこの方法を呼び出したが、name
はOptions.DefaultName
OptionsManager
はIOptions, IOptionsSnapshot
のインタフェースを継承しています.はっきりしているためかもしれません).カスタムプロファイル(JSON)
時々配置情報が多く、個別のファイルに配置したい、ASP.NET Coreは、INI、XML、JSONファイルシステムのロード構成方法を提供します.
CreateWebHostBuilder
メソッドには、次のコードが追加されています.public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
// , /Config
// `appsettings.json`
// config.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "Config"));
config.SetBasePath(Directory.GetCurrentDirectory());
// setting.json
//optional: , false
//reloadOnChange:
config.AddJsonFile("Config/setting.json", optional: false, reloadOnChange: false);
})
.UseStartup();
}
reloadOnChangeパラメータがどのようなことを処理しているかを見てみましょう.if (Source.ReloadOnChange && Source.FileProvider != null)
{
ChangeToken.OnChange(
// Load(true)
() => Source.FileProvider.Watch(Source.Path),
() => {
Thread.Sleep(Source.ReloadDelay);
Load(reload: true);
});
}
{
"Rookie": {
"Name": "DDD",
"Age": 12,
"Sex": " "
}
}
[Route("api/[controller]")]
[ApiController]
public class OptionsController : ControllerBase
{
private readonly IConfiguration _configuration;
public OptionsController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public string Index()
{
return JsonConvert.SerializeObject(new
{
Name = _configuration["Rookie:Name"],
Age = _configuration["Rookie:Age"],
Sex = _configuration["Rookie:Sex"]
});
}
}
上記の構成により、取得構成が
_configuration["Name"]
方式であることが判明し、次にオブジェクトにバインドするConfigureServices
メソッド追加コード:services.Configure(Configuration.GetSection("Rookie"));
GetSection
メソッド:指定キーを取得する構成サブセクションCreateWebHostBuilder
メソッドのコード:config.AddJsonFile("Config/setting.json", optional: false, reloadOnChange: true); {
"Name": "DDD",
"Age": 12,
"Sex": " "
}
ConfigureServices
メソッドに追加:var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("Config/setting.json", optional: false, reloadOnChange: true)
.Build();
services.Configure(config);
その他の方法
[Route("[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly TestOptions _bindOptions = new TestOptions();
private readonly Parent _parent = new Parent();
public HomeController(IConfiguration configuration)
{
//
_configuration.Bind(_bindOptions);
//
_configuration.GetSection("Parent").Bind(_parent);
}
[HttpGet("options")]
public string Options()
{
return JsonConvert.SerializeObject(new
{
BindOptions = _bindOptions,
Parent = _parent
});
}
}
人はこの方法が少し余計だと感じています(′□╰)services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>)));
services.TryAdd(ServiceDescriptor.Transient(typeof(IOptionsFactory<>), typeof(OptionsFactory<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>)));
を参照ここではIOptionsMonitor<>
: [Route("[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IOptionsMonitor _optionsMonitor;
public HomeController(IOptionsMonitor optionsMonitor
, ILogger logger)
{
_optionsMonitor = optionsMonitor;
_logger = logger;
}
[HttpGet("options")]
public string Options()
{
//
_optionsMonitor.OnChange((options, name) =>
{
var info = JsonConvert.SerializeObject(new
{
Options = options,
Name = name
});
_logger.LogInformation($" :{info}");
});
return JsonConvert.SerializeObject(new
{
OptionsMoitor = _optionsMonitor
});
}
プロファイルを変更するとログ情報が表示されます:info:WebApiSample.Controllers.HomeController[0]構成情報が変更されました:{"Options":{"ConnectionString":{data source=.;initial catalog=TEST;user id=sa","Parent":{"Child 1":"child","Child 2":{"GrandChildren":"grandchildren"}},"Name":"TestOptions"}info:WebApiSample.Controllers.HomeController[0]構成情報が変更されました:{"Options":{"ConnectionString":{data source=.;initial catalog=TEST;user id=sa","Parent":{"Child 1":"child","Child 2":{"GrandChildren":"grandchildren"}},"Name":"TestOptions"}info:WebApiSample.Controllers.HomeController[0]構成情報が変更されました:{"Options":{"ConnectionString":{data source=.;initial catalog=TEST;user id=sa","Parent":{"Child 1":"child","Child 2":{"GrandChildren":"grandchildren"}},"Name":"TestOptions"}info:WebApiSample.Controllers.HomeController[0]構成情報が変更されました:{"Options":{"ConnectionString":{data source=.;initial catalog=TEST;user id=sa","Parent":{"Child 1":"child","Child 2":{"GrandChildren":"grandchildren"}}},"Name":"TestOptions"}なぜこんなに多くのログがあるのか分かりません...また、どのログファイルを変更しても、AddJsonFile
が実行されたファイルであれば、このイベント最後に書く
, , ...
, 。
, !