Bu yanıtın yazıldığı sırada, appsettings.json
numaralı yapılandırma değerlerini yazmaya yönelik işlevselliği olan Microsoft.Extensions.Options
paketi tarafından sağlanan hiçbir bileşen bulunmadığı görülmüştür.
benim
ASP.NET Core
projelerinden biri ben bazı uygulama ayarlarını değiştirmek için kullanıcı etkinleştirme istedi - ve bu ayar değerleri eğer varsa yapılandırmaya eklenen alır isteğe bağlı bir
appsettings.custom.json
dosyasında daha precisly,
appsettings.json
saklanmalıdır. Bunun gibi
...
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();
}
Ben
IOptions<T>
uzanır
IWritableOptions<T>
arayüzü ilan; Bu yüzden ayarları okumak ve yazmak istediğimde
IOptions<T>
'u
IWritableOptions<T>
ile değiştirebilirim.
public interface IWritableOptions<out T> : IOptions<T> where T : class, new()
{
void Update(Action<T> applyChanges);
}
Ayrıca, bir yapılandırma bölümünü güncelleştirmek için IWritableOptions<T>
tarafından kullanılmak üzere tasarlanmıştır bir bileşeni olan IOptionsWriter
ile geldi. Bu daha önce belirtilen arayüzleri için benim uygulama ...
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();
}
}
yazar dosya yapısı hakkında haberdar olmadığı için, ben JObject
nesneler olarak bölümler işlemek için karar olduğunu. Erişimci istenen bölümü bulmaya çalışır ve T
örneğine gönderir, geçerli değeri kullanır (bulunmazsa) veya T
yeni bir örnek oluşturur, geçerli değer null
ise. Bu tutucu nesne, değişiklikleri ona uygulayacak olan arayana iletilir. Değiştirilen nesne bölümünü yerine gidiyor bir JToken
örneği ... Nihayet
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);
});
}
}
geri dönüştürülmüş olur daha, ben ...
beni kolayca yazılabilir seçenekleri erişimci yapılandırmak için izin
IServicesCollection
için bir uzantısı yöntemi uygulamaya benim
Controller
cl olarak
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
gibi kullanılabilecek
...
services.ConfigureWritable<CustomizableOptions>(this.Configuration,
"MySection", "appsettings.custom.json");
eşek sadece IOptions<T>
ile aynı özelliklere sahip bir IWritableOptions<CustomizableOptions>
örneğini talep edebilir, ancak aynı zamanda yapılandırma değerlerini değiştirip depolamasına izin verir.
private IWritableOptions<CustomizableOptions> options;
...
this.options.Update((opt) => {
opt.SampleOption = "...";
});
çerçeve yapılandırma değerlerini okumak için ortak bir altyapı sağlar, onları değiştirmek değil. Değişiklik söz konusu olduğunda, temel yapılandırma kaynağına erişmek ve değiştirmek için belirli yapılandırma sağlayıcısını kullanmanız gerekir. – haim770
"temel yapılandırma kaynağına erişmek ve değiştirmek için özel yapılandırma sağlayıcısı"? Başlamak için bana biraz referans verebilir misiniz? – 439
Değiştirmek istediğiniz yapılandırma kaynağı nedir? – haim770