Microsoft.Extensions.Options
パッケージで提供されるコンポーネントがこの回答を書いている時点で、構成値をappsettings.json
に書き戻す機能を持つように見えました。
は私
ASP.NET Core
プロジェクトの一つで、私はいくつかのアプリケーションの設定を変更するには、ユーザーを有効にしたかった - と、それらの設定値が存在する場合の構成に追加されるオプションの
appsettings.custom.json
ファイルによりprecisly、
appsettings.json
に格納する必要があります。このよう
...
public Startup(IHostingEnvironment env)
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.custom.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
私はIOptions<T>
を拡張IWritableOptions<T>
インタフェースを宣言しました。ですから、私は設定を読み書きしたいときはいつもをIWritableOptions<T>
に置き換えることができます。
public interface IWritableOptions<out T> : IOptions<T> where T : class, new()
{
void Update(Action<T> applyChanges);
}
また、Iは設定部を更新するためにIWritableOptions<T>
によって使用されることを意図しているコンポーネントである、IOptionsWriter
思い付きました。ライターは、ファイル構造について認識していないので、これは私がJObject
オブジェクトとしてセクションを処理することを決定し、...
class OptionsWriter : IOptionsWriter
{
private readonly IHostingEnvironment environment;
private readonly IConfigurationRoot configuration;
private readonly string file;
public OptionsWriter(
IHostingEnvironment environment,
IConfigurationRoot configuration,
string file)
{
this.environment = environment;
this.configuration = configuration;
this.file = file;
}
public void UpdateOptions(Action<JObject> callback, bool reload = true)
{
IFileProvider fileProvider = this.environment.ContentRootFileProvider;
IFileInfo fi = fileProvider.GetFileInfo(this.file);
JObject config = fileProvider.ReadJsonFileAsObject(fi);
callback(config);
using (var stream = File.OpenWrite(fi.PhysicalPath))
{
stream.SetLength(0);
config.WriteTo(stream);
}
this.configuration.Reload();
}
}
beforementionedインタフェースのための私の実装です。アクセサは要求されたセクションを見つけようとしてT
のインスタンスに逆シリアル化し、現在の値(見つからない場合)を使用します。現在の値がnull
の場合はT
の新しいインスタンスを作成します。このホルダーオブジェクトは、発信者に渡され、発信者に変更が適用されます。変更されたオブジェクトは、バック部分を置き換えるために起こっているJToken
インスタンスに変換されるよりも、...
class WritableOptions<T> : IWritableOptions<T> where T : class, new()
{
private readonly string sectionName;
private readonly IOptionsWriter writer;
private readonly IOptionsMonitor<T> options;
public WritableOptions(
string sectionName,
IOptionsWriter writer,
IOptionsMonitor<T> options)
{
this.sectionName = sectionName;
this.writer = writer;
this.options = options;
}
public T Value => this.options.CurrentValue;
public void Update(Action<T> applyChanges)
{
this.writer.UpdateOptions(opt =>
{
JToken section;
T sectionObject = opt.TryGetValue(this.sectionName, out section) ?
JsonConvert.DeserializeObject<T>(section.ToString()) :
this.options.CurrentValue ?? new T();
applyChanges(sectionObject);
string json = JsonConvert.SerializeObject(sectionObject);
opt[this.sectionName] = JObject.Parse(json);
});
}
}
は最後に、私は
...私は簡単に書き込み可能なオプションのアクセサを設定することができ
IServicesCollection
ために拡張メソッドを実装しました私
Controller
CLで
static class ServicesCollectionExtensions
{
public static void ConfigureWritable<T>(
this IServiceCollection services,
IConfigurationRoot configuration,
string sectionName,
string file) where T : class, new()
{
services.Configure<T>(configuration.GetSection(sectionName));
services.AddTransient<IWritableOptions<T>>(provider =>
{
var environment = provider.GetService<IHostingEnvironment>();
var options = provider.GetService<IOptionsMonitor<T>>();
IOptionsWriter writer = new OptionsWriter(environment, configuration, file);
return new WritableOptions<T>(sectionName, writer, options);
});
}
}
ConfigureServices
などに使用することができます
...
services.ConfigureWritable<CustomizableOptions>(this.Configuration,
"MySection", "appsettings.custom.json");
私はちょうどIWritableOptions<CustomizableOptions>
インスタンスを要求することができます。これはIOptions<T>
と同じ特性を持ちますが、設定値を変更して保存することもできます。
private IWritableOptions<CustomizableOptions> options;
...
this.options.Update((opt) => {
opt.SampleOption = "...";
});
フレームワークは、それらを変更しないように、設定値を読み込むための共通のインフラストラクチャを提供します。変更に関しては、特定の構成プロバイダーを使用して、基本構成ソースにアクセスして変更する必要があります。 – haim770
"基本設定ソースにアクセスして変更する特定の設定プロバイダ"?始めに参考にしてください。 – 439
変更しようとしている設定ソースは何ですか? – haim770