ASP.NET Core'da seçenek deseni
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Rick Anderson tarafından.
Seçenekler düzeni, ilgili ayar gruplarına kesin olarak belirlenmiş erişim sağlamak için sınıfları kullanır. Yapılandırma ayarları senaryoya göre ayrı sınıflar halinde yalıtıldığında, uygulama iki önemli yazılım mühendisliği ilkesine uyar:
- Kapsülleme:
- Yapılandırma ayarlarına bağlı sınıflar yalnızca kullandıkları yapılandırma ayarlarına bağlıdır.
- Endişelerin Ayrılması:
- Uygulamanın farklı bölümlerinin ayarları birbirine bağlı veya birbirine bağlı değildir.
Seçenekler ayrıca yapılandırma verilerini doğrulamak için bir mekanizma sağlar. Daha fazla bilgi için Seçenekler doğrulama bölümüne bakın.
Bu makalede, ASP.NET Core'daki seçenekler deseni hakkında bilgi sağlanır. Konsol uygulamalarında seçenekler desenini kullanma hakkında bilgi için bkz . .NET'te seçenekler deseni.
Hiyerarşik yapılandırmayı bağlama
İlgili yapılandırma değerlerini okumanın tercih edilen yolu seçenekler desenini kullanmaktır. Örneğin, aşağıdaki yapılandırma değerlerini okumak için:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Aşağıdaki PositionOptions
sınıflarını oluşturun:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Bir seçenekler sınıfı:
- Soyut olmamalıdır.
- Yapılandırmada karşılık gelen öğelere sahip türün genel okuma-yazma özelliklerine sahiptir.
- Yapılandırmadaki eşleşen girişlere bağlı okuma-yazma özelliklerine sahiptir.
- Alanları bağlı değil. Önceki örnekte,
Position
bağlı değildir.Position
alanı kullanıldığından,"Position"
öğesinin, sınıfı bir yapılandırma sağlayıcısına bağlarken uygulamada sabit kodlanmış olması gerekmez.
Aşağıdaki kod:
PositionOptions
sınıfını,Position
bölümüne bağlamak için ConfigurationBinder.Bind çağırır.Position
yapılandırma verisini görüntüler.
public class Test22Model : PageModel
{
private readonly IConfiguration Configuration;
public Test22Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var positionOptions = new PositionOptions();
Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
ConfigurationBinder.Get<T>
belirtilen türü bağlar ve döndürür. ConfigurationBinder.Get<T>
, ConfigurationBinder.Bind
kullanmaktan daha uygun olabilir. Aşağıdaki kod ConfigurationBinder.Get<T>
öğesinin, PositionOptions
sınıfıyla nasıl kullanılacağını göstermektedir:
public class Test21Model : PageModel
{
private readonly IConfiguration Configuration;
public PositionOptions? positionOptions { get; private set; }
public Test21Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
positionOptions = Configuration.GetSection(PositionOptions.Position)
.Get<PositionOptions>();
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Bind ayrıca soyut bir sınıfın birlesmesini de sağlar. soyut sınıfını SomethingWithAName
kullanan aşağıdaki kodu göz önünde bulundurun:
namespace ConfigSample.Options;
public abstract class SomethingWithAName
{
public abstract string? Name { get; set; }
}
public class NameTitleOptions(int age) : SomethingWithAName
{
public const string NameTitle = "NameTitle";
public override string? Name { get; set; }
public string Title { get; set; } = string.Empty;
public int Age { get; set; } = age;
}
Aşağıdaki kod yapılandırma değerlerini görüntüler NameTitleOptions
:
public class Test33Model : PageModel
{
private readonly IConfiguration Configuration;
public Test33Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var nameTitleOptions = new NameTitleOptions(22);
Configuration.GetSection(NameTitleOptions.NameTitle).Bind(nameTitleOptions);
return Content($"Title: {nameTitleOptions.Title} \n" +
$"Name: {nameTitleOptions.Name} \n" +
$"Age: {nameTitleOptions.Age}"
);
}
}
çağrısı Bind
, çağrısından daha Get<>
az katıdır:
Bind
soyutun birlesmesini sağlar.Get<>
bir örneğin kendisini oluşturması gerekir.
Seçenekler Deseni
Seçenekler desenini kullanırken alternatif bir yaklaşım, Position
bölümünü bağlamak ve bunu bağımlılık ekleme hizmet kapsayıcısına eklemektir. Aşağıdaki kodda PositionOptions
, Configure ile hizmet kapsayıcıya eklenmiş ve yapılandırmaya bağlanmıştır:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Aşağıdaki kod, önceki kodu kullanarak, konum seçeneklerini okur:
public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" +
$"Name: {_options.Name}");
}
}
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunmuyor . Uygulama başladıktan sonra değişiklikleri okumak için IOptionsSnapshot kullanın.
Seçenekler arabirimleri
- Desteklemez:
- Uygulama başlatıldıktan sonra yapılandırma verilerinin okunması.
- Adlandırılmış seçenekler
- Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Her istekte seçeneklerin yeniden derlenmesi gereken senaryolarda kullanışlıdır. Daha fazla bilgi için bkz . Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma.
- Scoped olarak kaydedilir ve bu nedenle Bir Singleton hizmetine eklenemez.
- Adlandırılmış seçenekleri destekler
- Örneklerin seçeneklerini almak ve seçenek bildirimlerini yönetmek için
TOptions
kullanılır. - Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Destekle -yen:
- Bildirimleri değiştirme
- adlandırılmış seçenekler
- Yeniden yüklenebilir yapılandırma
- Seçmeli seçenekler geçersiz kılınması (IOptionsMonitorCache<TOptions>)
Yapılandırma sonrası senaryolar, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra seçeneklerin ayarlanmasını veya değiştirilmesini sağlar.
IOptionsFactory<TOptions> yeni seçenek örnekleri oluşturmakla sorumludur. Tek Create bir yöntemi vardır. Varsayılan uygulama tüm kayıtlı IConfigureOptions<TOptions> ve IPostConfigureOptions<TOptions> tüm yapılandırmaları önce çalıştırır, ardından yapılandırma sonrası. ve IConfigureOptions<TOptions> arasında IConfigureNamedOptions<TOptions> ayrım gerçekleştirir ve yalnızca uygun arabirimi çağırır.
IOptionsMonitorCache<TOptions> tarafından IOptionsMonitor<TOptions> örnekleri önbelleğe TOptions
almak için kullanılır. değerin IOptionsMonitorCache<TOptions> yeniden derlenebilmesi için izleyicideki seçenek örneklerini geçersiz kılır (TryRemove). Değerler ile TryAddel ile tanıtılabilir. yöntemi Clear , tüm adlandırılmış örneklerin isteğe bağlı olarak yeniden oluşturulması gerektiğinde kullanılır.
Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma
kullanarak IOptionsSnapshot<TOptions>:
- Seçenekler, erişime erişildiğinde istek başına bir kez hesaplanır ve isteğin ömrü boyunca önbelleğe alınır.
- Kapsamlı bir hizmet olduğundan ve istek başına yeniden hesaplandığından önemli bir performans cezasına neden olabilir. Daha fazla bilgi için bu GitHub sorununa ve Yapılandırma bağlamasının performansını iyileştirme bölümüne bakın.
- Yapılandırma değişiklikleri, güncelleştirilmiş yapılandırma değerlerini okumayı destekleyen yapılandırma sağlayıcıları kullanılırken uygulama başlatıldıktan sonra okunur.
ile IOptionsSnapshot
arasındaki IOptionsMonitor
fark şudur:
IOptionsMonitor
, herhangi bir zamanda geçerli seçenek değerlerini alan bir Singleton hizmetidir ve bu da özellikle tek bağımlılıklarda yararlıdır.IOptionsSnapshot
Kapsamlı bir hizmettir ve nesne oluşturulurken seçeneklerinIOptionsSnapshot<T>
anlık görüntüsünü sağlar. Seçenekler anlık görüntüleri, geçici ve kapsamlı bağımlılıklarla kullanılmak üzere tasarlanmıştır.
Aşağıdaki kodda kullanılır IOptionsSnapshot<TOptions>.
public class TestSnapModel : PageModel
{
private readonly MyOptions _snapshotOptions;
public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
{
_snapshotOptions = snapshotOptionsAccessor.Value;
}
public ContentResult OnGet()
{
return Content($"Option1: {_snapshotOptions.Option1} \n" +
$"Option2: {_snapshotOptions.Option2}");
}
}
Aşağıdaki kod, şunlara bağlanan bir yapılandırma örneğini MyOptions
kaydeder:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
IOptionsMonitor
Aşağıdaki kod, ile bağlanan bir yapılandırma örneğini MyOptions
kaydeder.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Aşağıdaki örnek şunu kullanır IOptionsMonitor<TOptions>:
public class TestMonitorModel : PageModel
{
private readonly IOptionsMonitor<MyOptions> _optionsDelegate;
public TestMonitorModel(IOptionsMonitor<MyOptions> optionsDelegate )
{
_optionsDelegate = optionsDelegate;
}
public ContentResult OnGet()
{
return Content($"Option1: {_optionsDelegate.CurrentValue.Option1} \n" +
$"Option2: {_optionsDelegate.CurrentValue.Option2}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Adlandırılmış seçenekler IConfigureNamedOptions'ın kullanılmasını destekler
Adlandırılmış seçenekler:
- Birden çok yapılandırma bölümü aynı özelliklere bağlandığında kullanışlıdır.
- Büyük/küçük harfe duyarlıdır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
ve TopItem:Year
bağlamak TopItem:Month
için iki sınıf oluşturmak yerine, her bölüm için aşağıdaki sınıf kullanılır:
public class TopItemSettings
{
public const string Month = "Month";
public const string Year = "Year";
public string Name { get; set; } = string.Empty;
public string Model { get; set; } = string.Empty;
}
Aşağıdaki kod adlandırılmış seçenekleri yapılandırıyor:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<TopItemSettings>(TopItemSettings.Month,
builder.Configuration.GetSection("TopItem:Month"));
builder.Services.Configure<TopItemSettings>(TopItemSettings.Year,
builder.Configuration.GetSection("TopItem:Year"));
var app = builder.Build();
Aşağıdaki kod adlandırılmış seçenekleri görüntüler:
public class TestNOModel : PageModel
{
private readonly TopItemSettings _monthTopItem;
private readonly TopItemSettings _yearTopItem;
public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
{
_monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
_yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
}
public ContentResult OnGet()
{
return Content($"Month:Name {_monthTopItem.Name} \n" +
$"Month:Model {_monthTopItem.Model} \n\n" +
$"Year:Name {_yearTopItem.Name} \n" +
$"Year:Model {_yearTopItem.Model} \n" );
}
}
Tüm seçenekler adlandırılmış örneklerdir. IConfigureOptions<TOptions>örnekleri, örneğini hedefleme Options.DefaultName
olarak değerlendirilir.string.Empty
IConfigureNamedOptions<TOptions> ayrıca uygular IConfigureOptions<TOptions>. varsayılan uygulamasının IOptionsFactory<TOptions> her birini uygun şekilde kullanmak için mantığı vardır. null
Adlandırılmış seçenek, belirli bir adlandırılmış örnek yerine tüm adlandırılmış örnekleri hedeflemek için kullanılır. ConfigureAll ve PostConfigureAll bu kuralı kullanın.
OptionsBuilder API'si
OptionsBuilder<TOptions> örnekleri yapılandırmak TOptions
için kullanılır. OptionsBuilder
sonraki tüm çağrılarda görüntülenmek yerine ilk AddOptions<TOptions>(string optionsName)
çağrının yalnızca tek bir parametresi olduğundan adlandırılmış seçeneklerin oluşturulmasını kolaylaştırır. Seçenek doğrulama ve ConfigureOptions
hizmet bağımlılıklarını kabul eden aşırı yüklemeler yalnızca aracılığıyla OptionsBuilder
kullanılabilir.
OptionsBuilder
, Seçenekler doğrulama bölümünde kullanılır.
Özel depo ekleme hakkında bilgi için bkz. Özel depo yapılandırmak için AddOptions kullanma.
Seçenekleri yapılandırmak için DI hizmetlerini kullanma
Hizmetlere bağımlılık eklemeden erişilirken seçenekler iki şekilde yapılandırılabilir:
üzerinde OptionsBuilder<TOptions>öğesine Configure bir yapılandırma temsilcisi geçirin.
OptionsBuilder<TOptions>
, seçenekleri yapılandırmak için beş adede kadar hizmetin kullanılmasına izin veren aşırı yüklemeler Configure sağlar:builder.Services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));
veya IConfigureNamedOptions<TOptions> uygulayan IConfigureOptions<TOptions> bir tür oluşturun ve türü hizmet olarak kaydedin.
Hizmet oluşturmak daha karmaşık olduğundan, öğesine bir yapılandırma temsilcisi Configuregeçirmenizi öneririz. Tür oluşturmak, çağırırken Configureçerçevenin yaptıklarına eşdeğerdir. Çağrısı Configure , belirtilen genel IConfigureNamedOptions<TOptions>hizmet türlerini kabul eden bir oluşturucuya sahip olan geçici bir genel kaydeder.
Seçenekler doğrulaması
Seçenekler doğrulaması, seçenek değerlerinin doğrulanmasına olanak tanır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
Yapılandırma bölümüne bağlanmak için "MyConfig"
aşağıdaki sınıf kullanılır ve birkaç DataAnnotations
kural uygular:
public class MyConfigOptions
{
public const string MyConfig = "MyConfig";
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")]
public string Key1 { get; set; }
[Range(0, 1000,
ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Key2 { get; set; }
public int Key3 { get; set; }
}
Aşağıdaki kod:
- Sınıfa bağlanan bir OptionsBuilder<TOptions> almak için
MyConfigOptions
çağrılarAddOptions. - kullanarak
DataAnnotations
doğrulamayı etkinleştirmek için çağrılarValidateDataAnnotations.
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations();
var app = builder.Build();
ValidateDataAnnotations
Uzantı yöntemi, Microsoft.Extensions.Options.DataAnnotations NuGet paketinde tanımlanır. SDK kullanan web uygulamaları için bu pakete Microsoft.NET.Sdk.Web
paylaşılan çerçeveden örtük olarak başvurulur.
Aşağıdaki kod yapılandırma değerlerini veya doğrulama hatalarını görüntüler:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IOptions<MyConfigOptions> _config;
public HomeController(IOptions<MyConfigOptions> config,
ILogger<HomeController> logger)
{
_config = config;
_logger = logger;
try
{
var configValue = _config.Value;
}
catch (OptionsValidationException ex)
{
foreach (var failure in ex.Failures)
{
_logger.LogError(failure);
}
}
}
public ContentResult Index()
{
string msg;
try
{
msg = $"Key1: {_config.Value.Key1} \n" +
$"Key2: {_config.Value.Key2} \n" +
$"Key3: {_config.Value.Key3}";
}
catch (OptionsValidationException optValEx)
{
return Content(optValEx.Message);
}
return Content(msg);
}
Aşağıdaki kod, temsilci kullanarak daha karmaşık bir doğrulama kuralı uygular:
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.Key2 != 0)
{
return config.Key3 > config.Key2;
}
return true;
}, "Key3 must be > than Key2."); // Failure message.
var app = builder.Build();
IValidateOptions<TOptions>
ve IValidatableObject
Aşağıdaki sınıf şunu uygular IValidateOptions<TOptions>:
public class MyConfigValidation : IValidateOptions<MyConfigOptions>
{
public MyConfigOptions _config { get; private set; }
public MyConfigValidation(IConfiguration config)
{
_config = config.GetSection(MyConfigOptions.MyConfig)
.Get<MyConfigOptions>();
}
public ValidateOptionsResult Validate(string name, MyConfigOptions options)
{
string? vor = null;
var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$");
var match = rx.Match(options.Key1!);
if (string.IsNullOrEmpty(match.Value))
{
vor = $"{options.Key1} doesn't match RegEx \n";
}
if ( options.Key2 < 0 || options.Key2 > 1000)
{
vor = $"{options.Key2} doesn't match Range 0 - 1000 \n";
}
if (_config.Key2 != default)
{
if(_config.Key3 <= _config.Key2)
{
vor += "Key3 must be > than Key2.";
}
}
if (vor != null)
{
return ValidateOptionsResult.Fail(vor);
}
return ValidateOptionsResult.Success;
}
}
IValidateOptions
, doğrulama kodunun sınıfın Program.cs
dışına ve içine taşınmasını sağlar.
Yukarıdaki kod kullanılarak doğrulama aşağıdaki kodla etkinleştirilir Program.cs
:
using Microsoft.Extensions.Options;
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.Configure<MyConfigOptions>(builder.Configuration.GetSection(
MyConfigOptions.MyConfig));
builder.Services.AddSingleton<IValidateOptions
<MyConfigOptions>, MyConfigValidation>();
var app = builder.Build();
Seçenekler doğrulaması da destekler IValidatableObject. Sınıfın kendi içinde sınıf düzeyinde doğrulama gerçekleştirmek için:
- arabirimini
IValidatableObject
ve Validate yöntemini sınıfı içinde uygulayın. - çağrısında ValidateDataAnnotations bulunur
Program.cs
.
ValidateOnStart
Seçenek doğrulama, bir TOption
örnek ilk kez oluşturulduğunda çalışır. Bu, örneğin bir istek işlem hattında ilk kez erişim IOptionsSnapshot<TOptions>.Value
gerçekleştiğinde veya mevcut ayarlarda çağrıldığında IOptionsMonitor<TOptions>.Get(string)
anlamına gelir. Ayarlar yeniden yüklendikten sonra doğrulama yeniden çalışır. ASP.NET Core çalışma zamanı, oluşturulduktan sonra seçenekler örneğini önbelleğe almak için kullanır OptionsCache<TOptions> .
Seçenek doğrulamayı hevesle çalıştırmak için, uygulama başlatıldığında çağrısı ValidateOnStart<TOptions>(OptionsBuilder<TOptions>)yapın Program.cs
:
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.ValidateOnStart();
Yapılandırma sonrası seçenekler
ile IPostConfigureOptions<TOptions>yapılandırma sonrası ayarlayın. Yapılandırma sonrası, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra çalıştırılır:
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig));
builder.Services.PostConfigure<MyConfigOptions>(myOptions =>
{
myOptions.Key1 = "post_configured_key1_value";
});
PostConfigure , adlandırılmış seçenekleri yapılandırma sonrası için kullanılabilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<TopItemSettings>(TopItemSettings.Month,
builder.Configuration.GetSection("TopItem:Month"));
builder.Services.Configure<TopItemSettings>(TopItemSettings.Year,
builder.Configuration.GetSection("TopItem:Year"));
builder.Services.PostConfigure<TopItemSettings>("Month", myOptions =>
{
myOptions.Name = "post_configured_name_value";
myOptions.Model = "post_configured_model_value";
});
var app = builder.Build();
Tüm yapılandırma örneklerini yapılandırma sonrası yapılandırmak için kullanın PostConfigureAll :
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig));
builder.Services.PostConfigureAll<MyConfigOptions>(myOptions =>
{
myOptions.Key1 = "post_configured_key1_value";
});
uygulamasındaki erişim seçenekleri Program.cs
'a erişmek IOptions<TOptions> veya IOptionsMonitor<TOptions> içinde Program.cs
öğesini aramak GetRequiredService için:WebApplication.Services
var app = builder.Build();
var option1 = app.Services.GetRequiredService<IOptionsMonitor<MyOptions>>()
.CurrentValue.Option1;
Ek kaynaklar
Kirk Larkin ve Rick Anderson tarafından.
Seçenekler düzeni, ilgili ayar gruplarına kesin olarak belirlenmiş erişim sağlamak için sınıfları kullanır. Yapılandırma ayarları senaryoya göre ayrı sınıflar halinde yalıtıldığında, uygulama iki önemli yazılım mühendisliği ilkesine uyar:
- Kapsülleme:
- Yapılandırma ayarlarına bağlı sınıflar yalnızca kullandıkları yapılandırma ayarlarına bağlıdır.
- Endişelerin Ayrılması:
- Uygulamanın farklı bölümlerinin ayarları birbirine bağlı veya birbirine bağlı değildir.
Seçenekler ayrıca yapılandırma verilerini doğrulamak için bir mekanizma sağlar. Daha fazla bilgi için Seçenekler doğrulama bölümüne bakın.
Bu makalede, ASP.NET Core'daki seçenekler deseni hakkında bilgi sağlanır. Konsol uygulamalarında seçenekler desenini kullanma hakkında bilgi için bkz . .NET'te seçenekler deseni.
Hiyerarşik yapılandırmayı bağlama
İlgili yapılandırma değerlerini okumanın tercih edilen yolu seçenekler desenini kullanmaktır. Örneğin, aşağıdaki yapılandırma değerlerini okumak için:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Aşağıdaki PositionOptions
sınıflarını oluşturun:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Bir seçenekler sınıfı:
- Genel bir parametresiz oluşturucu ile soyut olmamalıdır.
- Türün tüm genel okuma-yazma özellikleri bağlıdır.
- Alanlar bağlı değildir. Önceki örnekte,
Position
bağlı değildir.Position
alanı kullanıldığından,"Position"
öğesinin, sınıfı bir yapılandırma sağlayıcısına bağlarken uygulamada sabit kodlanmış olması gerekmez.
Aşağıdaki kod:
PositionOptions
sınıfını,Position
bölümüne bağlamak için ConfigurationBinder.Bind çağırır.Position
yapılandırma verisini görüntüler.
public class Test22Model : PageModel
{
private readonly IConfiguration Configuration;
public Test22Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var positionOptions = new PositionOptions();
Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
ConfigurationBinder.Get<T>
belirtilen türü bağlar ve döndürür. ConfigurationBinder.Get<T>
, ConfigurationBinder.Bind
kullanmaktan daha uygun olabilir. Aşağıdaki kod ConfigurationBinder.Get<T>
öğesinin, PositionOptions
sınıfıyla nasıl kullanılacağını göstermektedir:
public class Test21Model : PageModel
{
private readonly IConfiguration Configuration;
public PositionOptions? positionOptions { get; private set; }
public Test21Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
positionOptions = Configuration.GetSection(PositionOptions.Position)
.Get<PositionOptions>();
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Seçenekler desenini kullanırken alternatif bir yaklaşım, Position
bölümünü bağlamak ve bunu bağımlılık ekleme hizmet kapsayıcısına eklemektir. Aşağıdaki kodda PositionOptions
, Configure ile hizmet kapsayıcıya eklenmiş ve yapılandırmaya bağlanmıştır:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Aşağıdaki kod, önceki kodu kullanarak, konum seçeneklerini okur:
public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" +
$"Name: {_options.Name}");
}
}
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunmuyor . Uygulama başladıktan sonra değişiklikleri okumak için IOptionsSnapshot kullanın.
Seçenekler arabirimleri
- Desteklemez:
- Uygulama başlatıldıktan sonra yapılandırma verilerinin okunması.
- Adlandırılmış seçenekler
- Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Her istekte seçeneklerin yeniden derlenmesi gereken senaryolarda kullanışlıdır. Daha fazla bilgi için bkz . Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma.
- Scoped olarak kaydedilir ve bu nedenle Bir Singleton hizmetine eklenemez.
- Adlandırılmış seçenekleri destekler
- Örneklerin seçeneklerini almak ve seçenek bildirimlerini yönetmek için
TOptions
kullanılır. - Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Destekle -yen:
- Bildirimleri değiştirme
- adlandırılmış seçenekler
- Yeniden yüklenebilir yapılandırma
- Seçmeli seçenekler geçersiz kılınması (IOptionsMonitorCache<TOptions>)
Yapılandırma sonrası senaryolar, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra seçeneklerin ayarlanmasını veya değiştirilmesini sağlar.
IOptionsFactory<TOptions> yeni seçenek örnekleri oluşturmakla sorumludur. Tek Create bir yöntemi vardır. Varsayılan uygulama tüm kayıtlı IConfigureOptions<TOptions> ve IPostConfigureOptions<TOptions> tüm yapılandırmaları önce çalıştırır, ardından yapılandırma sonrası. ve IConfigureOptions<TOptions> arasında IConfigureNamedOptions<TOptions> ayrım gerçekleştirir ve yalnızca uygun arabirimi çağırır.
IOptionsMonitorCache<TOptions> tarafından IOptionsMonitor<TOptions> örnekleri önbelleğe TOptions
almak için kullanılır. değerin IOptionsMonitorCache<TOptions> yeniden derlenebilmesi için izleyicideki seçenek örneklerini geçersiz kılır (TryRemove). Değerler ile TryAddel ile tanıtılabilir. yöntemi Clear , tüm adlandırılmış örneklerin isteğe bağlı olarak yeniden oluşturulması gerektiğinde kullanılır.
Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma
kullanarak IOptionsSnapshot<TOptions>:
- Seçenekler, erişime erişildiğinde istek başına bir kez hesaplanır ve isteğin ömrü boyunca önbelleğe alınır.
- Kapsamlı bir hizmet olduğundan ve istek başına yeniden hesaplandığından önemli bir performans cezasına neden olabilir. Daha fazla bilgi için bu GitHub sorununa ve Yapılandırma bağlamasının performansını iyileştirme bölümüne bakın.
- Yapılandırma değişiklikleri, güncelleştirilmiş yapılandırma değerlerini okumayı destekleyen yapılandırma sağlayıcıları kullanılırken uygulama başlatıldıktan sonra okunur.
ile IOptionsSnapshot
arasındaki IOptionsMonitor
fark şudur:
IOptionsMonitor
, herhangi bir zamanda geçerli seçenek değerlerini alan bir Singleton hizmetidir ve bu da özellikle tek bağımlılıklarda yararlıdır.IOptionsSnapshot
Kapsamlı bir hizmettir ve nesne oluşturulurken seçeneklerinIOptionsSnapshot<T>
anlık görüntüsünü sağlar. Seçenekler anlık görüntüleri, geçici ve kapsamlı bağımlılıklarla kullanılmak üzere tasarlanmıştır.
Aşağıdaki kodda kullanılır IOptionsSnapshot<TOptions>.
public class TestSnapModel : PageModel
{
private readonly MyOptions _snapshotOptions;
public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
{
_snapshotOptions = snapshotOptionsAccessor.Value;
}
public ContentResult OnGet()
{
return Content($"Option1: {_snapshotOptions.Option1} \n" +
$"Option2: {_snapshotOptions.Option2}");
}
}
Aşağıdaki kod, şunlara bağlanan bir yapılandırma örneğini MyOptions
kaydeder:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
IOptionsMonitor
Aşağıdaki kod, ile bağlanan bir yapılandırma örneğini MyOptions
kaydeder.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Aşağıdaki örnek şunu kullanır IOptionsMonitor<TOptions>:
public class TestMonitorModel : PageModel
{
private readonly IOptionsMonitor<MyOptions> _optionsDelegate;
public TestMonitorModel(IOptionsMonitor<MyOptions> optionsDelegate )
{
_optionsDelegate = optionsDelegate;
}
public ContentResult OnGet()
{
return Content($"Option1: {_optionsDelegate.CurrentValue.Option1} \n" +
$"Option2: {_optionsDelegate.CurrentValue.Option2}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Adlandırılmış seçenekler IConfigureNamedOptions'ın kullanılmasını destekler
Adlandırılmış seçenekler:
- Birden çok yapılandırma bölümü aynı özelliklere bağlandığında kullanışlıdır.
- Büyük/küçük harfe duyarlıdır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
ve TopItem:Year
bağlamak TopItem:Month
için iki sınıf oluşturmak yerine, her bölüm için aşağıdaki sınıf kullanılır:
public class TopItemSettings
{
public const string Month = "Month";
public const string Year = "Year";
public string Name { get; set; } = string.Empty;
public string Model { get; set; } = string.Empty;
}
Aşağıdaki kod adlandırılmış seçenekleri yapılandırıyor:
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<TopItemSettings>(TopItemSettings.Month,
builder.Configuration.GetSection("TopItem:Month"));
builder.Services.Configure<TopItemSettings>(TopItemSettings.Year,
builder.Configuration.GetSection("TopItem:Year"));
var app = builder.Build();
Aşağıdaki kod adlandırılmış seçenekleri görüntüler:
public class TestNOModel : PageModel
{
private readonly TopItemSettings _monthTopItem;
private readonly TopItemSettings _yearTopItem;
public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
{
_monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
_yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
}
public ContentResult OnGet()
{
return Content($"Month:Name {_monthTopItem.Name} \n" +
$"Month:Model {_monthTopItem.Model} \n\n" +
$"Year:Name {_yearTopItem.Name} \n" +
$"Year:Model {_yearTopItem.Model} \n" );
}
}
Tüm seçenekler adlandırılmış örneklerdir. IConfigureOptions<TOptions>örnekleri, örneğini hedefleme Options.DefaultName
olarak değerlendirilir.string.Empty
IConfigureNamedOptions<TOptions> ayrıca uygular IConfigureOptions<TOptions>. varsayılan uygulamasının IOptionsFactory<TOptions> her birini uygun şekilde kullanmak için mantığı vardır. null
Adlandırılmış seçenek, belirli bir adlandırılmış örnek yerine tüm adlandırılmış örnekleri hedeflemek için kullanılır. ConfigureAll ve PostConfigureAll bu kuralı kullanın.
OptionsBuilder API'si
OptionsBuilder<TOptions> örnekleri yapılandırmak TOptions
için kullanılır. OptionsBuilder
sonraki tüm çağrılarda görüntülenmek yerine ilk AddOptions<TOptions>(string optionsName)
çağrının yalnızca tek bir parametresi olduğundan adlandırılmış seçeneklerin oluşturulmasını kolaylaştırır. Seçenek doğrulama ve ConfigureOptions
hizmet bağımlılıklarını kabul eden aşırı yüklemeler yalnızca aracılığıyla OptionsBuilder
kullanılabilir.
OptionsBuilder
, Seçenekler doğrulama bölümünde kullanılır.
Özel depo ekleme hakkında bilgi için bkz. Özel depo yapılandırmak için AddOptions kullanma.
Seçenekleri yapılandırmak için DI hizmetlerini kullanma
Hizmetlere bağımlılık eklemeden erişilirken seçenekler iki şekilde yapılandırılabilir:
üzerinde OptionsBuilder<TOptions>öğesine Configure bir yapılandırma temsilcisi geçirin.
OptionsBuilder<TOptions>
, seçenekleri yapılandırmak için beş adede kadar hizmetin kullanılmasına izin veren aşırı yüklemeler Configure sağlar:builder.Services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));
veya IConfigureNamedOptions<TOptions> uygulayan IConfigureOptions<TOptions> bir tür oluşturun ve türü hizmet olarak kaydedin.
Hizmet oluşturmak daha karmaşık olduğundan, öğesine bir yapılandırma temsilcisi Configuregeçirmenizi öneririz. Tür oluşturmak, çağırırken Configureçerçevenin yaptıklarına eşdeğerdir. Çağrısı Configure , belirtilen genel IConfigureNamedOptions<TOptions>hizmet türlerini kabul eden bir oluşturucuya sahip olan geçici bir genel kaydeder.
Seçenekler doğrulaması
Seçenekler doğrulaması, seçenek değerlerinin doğrulanmasına olanak tanır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
Yapılandırma bölümüne bağlanmak için "MyConfig"
aşağıdaki sınıf kullanılır ve birkaç DataAnnotations
kural uygular:
public class MyConfigOptions
{
public const string MyConfig = "MyConfig";
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")]
public string Key1 { get; set; }
[Range(0, 1000,
ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Key2 { get; set; }
public int Key3 { get; set; }
}
Aşağıdaki kod:
- Sınıfa bağlanan bir OptionsBuilder<TOptions> almak için
MyConfigOptions
çağrılarAddOptions. - kullanarak
DataAnnotations
doğrulamayı etkinleştirmek için çağrılarValidateDataAnnotations.
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations();
var app = builder.Build();
ValidateDataAnnotations
Uzantı yöntemi, Microsoft.Extensions.Options.DataAnnotations NuGet paketinde tanımlanır. SDK kullanan web uygulamaları için bu pakete Microsoft.NET.Sdk.Web
paylaşılan çerçeveden örtük olarak başvurulur.
Aşağıdaki kod yapılandırma değerlerini veya doğrulama hatalarını görüntüler:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IOptions<MyConfigOptions> _config;
public HomeController(IOptions<MyConfigOptions> config,
ILogger<HomeController> logger)
{
_config = config;
_logger = logger;
try
{
var configValue = _config.Value;
}
catch (OptionsValidationException ex)
{
foreach (var failure in ex.Failures)
{
_logger.LogError(failure);
}
}
}
public ContentResult Index()
{
string msg;
try
{
msg = $"Key1: {_config.Value.Key1} \n" +
$"Key2: {_config.Value.Key2} \n" +
$"Key3: {_config.Value.Key3}";
}
catch (OptionsValidationException optValEx)
{
return Content(optValEx.Message);
}
return Content(msg);
}
Aşağıdaki kod, temsilci kullanarak daha karmaşık bir doğrulama kuralı uygular:
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.Key2 != 0)
{
return config.Key3 > config.Key2;
}
return true;
}, "Key3 must be > than Key2."); // Failure message.
var app = builder.Build();
IValidateOptions<TOptions>
ve IValidatableObject
Aşağıdaki sınıf şunu uygular IValidateOptions<TOptions>:
public class MyConfigValidation : IValidateOptions<MyConfigOptions>
{
public MyConfigOptions _config { get; private set; }
public MyConfigValidation(IConfiguration config)
{
_config = config.GetSection(MyConfigOptions.MyConfig)
.Get<MyConfigOptions>();
}
public ValidateOptionsResult Validate(string name, MyConfigOptions options)
{
string? vor = null;
var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$");
var match = rx.Match(options.Key1!);
if (string.IsNullOrEmpty(match.Value))
{
vor = $"{options.Key1} doesn't match RegEx \n";
}
if ( options.Key2 < 0 || options.Key2 > 1000)
{
vor = $"{options.Key2} doesn't match Range 0 - 1000 \n";
}
if (_config.Key2 != default)
{
if(_config.Key3 <= _config.Key2)
{
vor += "Key3 must be > than Key2.";
}
}
if (vor != null)
{
return ValidateOptionsResult.Fail(vor);
}
return ValidateOptionsResult.Success;
}
}
IValidateOptions
, doğrulama kodunun sınıfın Program.cs
dışına ve içine taşınmasını sağlar.
Yukarıdaki kod kullanılarak doğrulama aşağıdaki kodla etkinleştirilir Program.cs
:
using Microsoft.Extensions.Options;
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.Configure<MyConfigOptions>(builder.Configuration.GetSection(
MyConfigOptions.MyConfig));
builder.Services.AddSingleton<IValidateOptions
<MyConfigOptions>, MyConfigValidation>();
var app = builder.Build();
Seçenekler doğrulaması da destekler IValidatableObject. Sınıfın kendi içinde sınıf düzeyinde doğrulama gerçekleştirmek için:
- arabirimini
IValidatableObject
ve Validate yöntemini sınıfı içinde uygulayın. - çağrısında ValidateDataAnnotations bulunur
Program.cs
.
ValidateOnStart
Seçenek doğrulama, bir IOptions<TOptions>, IOptionsSnapshot<TOptions>veya IOptionsMonitor<TOptions> uygulaması ilk kez oluşturulduğunda çalışır. Seçenek doğrulamayı hevesle çalıştırmak için, uygulama başlatıldığında çağrısı ValidateOnStart yapın Program.cs
:
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.ValidateOnStart();
Yapılandırma sonrası seçenekler
ile IPostConfigureOptions<TOptions>yapılandırma sonrası ayarlayın. Yapılandırma sonrası, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra çalıştırılır:
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig));
builder.Services.PostConfigure<MyConfigOptions>(myOptions =>
{
myOptions.Key1 = "post_configured_key1_value";
});
PostConfigure , adlandırılmış seçenekleri yapılandırma sonrası için kullanılabilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<TopItemSettings>(TopItemSettings.Month,
builder.Configuration.GetSection("TopItem:Month"));
builder.Services.Configure<TopItemSettings>(TopItemSettings.Year,
builder.Configuration.GetSection("TopItem:Year"));
builder.Services.PostConfigure<TopItemSettings>("Month", myOptions =>
{
myOptions.Name = "post_configured_name_value";
myOptions.Model = "post_configured_model_value";
});
var app = builder.Build();
Tüm yapılandırma örneklerini yapılandırma sonrası yapılandırmak için kullanın PostConfigureAll :
using OptionsValidationSample.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig));
builder.Services.PostConfigureAll<MyConfigOptions>(myOptions =>
{
myOptions.Key1 = "post_configured_key1_value";
});
uygulamasındaki erişim seçenekleri Program.cs
'a erişmek IOptions<TOptions> veya IOptionsMonitor<TOptions> içinde Program.cs
öğesini aramak GetRequiredService için:WebApplication.Services
var app = builder.Build();
var option1 = app.Services.GetRequiredService<IOptionsMonitor<MyOptions>>()
.CurrentValue.Option1;
Ek kaynaklar
Kirk Larkin ve Rick Anderson tarafından.
Seçenekler düzeni, ilgili ayar gruplarına kesin olarak belirlenmiş erişim sağlamak için sınıfları kullanır. Yapılandırma ayarları senaryoya göre ayrı sınıflar halinde yalıtıldığında, uygulama iki önemli yazılım mühendisliği ilkesine uyar:
- Kapsülleme:
- Yapılandırma ayarlarına bağlı sınıflar yalnızca kullandıkları yapılandırma ayarlarına bağlıdır.
- Endişelerin Ayrılması:
- Uygulamanın farklı bölümlerinin ayarları birbirine bağlı veya birbirine bağlı değildir.
Seçenekler ayrıca yapılandırma verilerini doğrulamak için bir mekanizma sağlar. Daha fazla bilgi için Seçenekler doğrulama bölümüne bakın.
Bu konu, ASP.NET Core'daki seçenekler deseni hakkında bilgi sağlar. Konsol uygulamalarında seçenekler desenini kullanma hakkında bilgi için bkz . .NET'te seçenekler deseni.
Örnek kodu görüntüleme veya indirme (indirme)
Hiyerarşik yapılandırmayı bağlama
İlgili yapılandırma değerlerini okumanın tercih edilen yolu seçenekler desenini kullanmaktır. Örneğin, aşağıdaki yapılandırma değerlerini okumak için:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Aşağıdaki PositionOptions
sınıflarını oluşturun:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; }
public string Name { get; set; }
}
Bir seçenekler sınıfı:
- Genel bir parametresiz oluşturucu ile soyut olmamalıdır.
- Türün tüm genel okuma-yazma özellikleri bağlıdır.
- Alanlar bağlı değildir. Önceki örnekte,
Position
bağlı değildir.Position
özelliği kullanıldığından,"Position"
öğesinin, sınıfı bir yapılandırma sağlayıcısına bağlarken uygulamada sabit kodlanmış olması gerekmez.
Aşağıdaki kod:
PositionOptions
sınıfını,Position
bölümüne bağlamak için ConfigurationBinder.Bind çağırır.Position
yapılandırma verisini görüntüler.
public class Test22Model : PageModel
{
private readonly IConfiguration Configuration;
public Test22Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var positionOptions = new PositionOptions();
Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
ConfigurationBinder.Get<T>
belirtilen türü bağlar ve döndürür. ConfigurationBinder.Get<T>
, ConfigurationBinder.Bind
kullanmaktan daha uygun olabilir. Aşağıdaki kod ConfigurationBinder.Get<T>
öğesinin, PositionOptions
sınıfıyla nasıl kullanılacağını göstermektedir:
public class Test21Model : PageModel
{
private readonly IConfiguration Configuration;
public PositionOptions positionOptions { get; private set; }
public Test21Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
positionOptions = Configuration.GetSection(PositionOptions.Position)
.Get<PositionOptions>();
return Content($"Title: {positionOptions.Title} \n" +
$"Name: {positionOptions.Name}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Seçenekler desenini kullanırken alternatif bir yaklaşım, Position
bölümünü bağlamak ve bunu bağımlılık ekleme hizmet kapsayıcısına eklemektir. Aşağıdaki kodda PositionOptions
, Configure ile hizmet kapsayıcıya eklenmiş ve yapılandırmaya bağlanmıştır:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<PositionOptions>(Configuration.GetSection(
PositionOptions.Position));
services.AddRazorPages();
}
Aşağıdaki kod, önceki kodu kullanarak, konum seçeneklerini okur:
public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" +
$"Name: {_options.Name}");
}
}
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunmuyor . Uygulama başladıktan sonra değişiklikleri okumak için IOptionsSnapshot kullanın.
Seçenekler arabirimleri
- Desteklemez:
- Uygulama başlatıldıktan sonra yapılandırma verilerinin okunması.
- Adlandırılmış seçenekler
- Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Her istekte seçeneklerin yeniden derlenmesi gereken senaryolarda kullanışlıdır. Daha fazla bilgi için bkz . Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma.
- Kapsamlı olarak kaydedilir ve bu nedenle bir Singleton hizmetine eklenemez.
- Adlandırılmış seçenekleri destekler
- Örneklerin seçeneklerini almak ve seçenek bildirimlerini yönetmek için
TOptions
kullanılır. - Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne eklenebilir.
- Destekle -yen:
- Bildirimleri değiştirme
- Adlandırılmış seçenekler
- Yeniden yüklenebilir yapılandırma
- Seçmeli seçenekler geçersiz kılınması (IOptionsMonitorCache<TOptions>)
Yapılandırma sonrası senaryolar, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra seçeneklerin ayarlanmasını veya değiştirilmesini sağlar.
IOptionsFactory<TOptions> yeni seçenek örnekleri oluşturmakla sorumludur. Tek Create bir yöntemi vardır. Varsayılan uygulama tüm kayıtlı IConfigureOptions<TOptions> ve IPostConfigureOptions<TOptions> tüm yapılandırmaları önce çalıştırır, ardından yapılandırma sonrası. ve IConfigureOptions<TOptions> arasında IConfigureNamedOptions<TOptions> ayrım gerçekleştirir ve yalnızca uygun arabirimi çağırır.
IOptionsMonitorCache<TOptions> tarafından IOptionsMonitor<TOptions> örnekleri önbelleğe TOptions
almak için kullanılır. değerin IOptionsMonitorCache<TOptions> yeniden derlenebilmesi için izleyicideki seçenek örneklerini geçersiz kılır (TryRemove). Değerler ile TryAddel ile tanıtılabilir. yöntemi Clear , tüm adlandırılmış örneklerin isteğe bağlı olarak yeniden oluşturulması gerektiğinde kullanılır.
Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma
kullanılarak IOptionsSnapshot<TOptions>, seçenekler istek başına bir kez hesaplanır ve isteğin ömrü boyunca önbelleğe alınır. Yapılandırma değişiklikleri, güncelleştirilmiş yapılandırma değerlerini okumayı destekleyen yapılandırma sağlayıcıları kullanılırken uygulama başlatıldıktan sonra okunur.
ile IOptionsSnapshot
arasındaki IOptionsMonitor
fark şudur:
IOptionsMonitor
, herhangi bir zamanda geçerli seçenek değerlerini alan bir Singleton hizmetidir ve bu da özellikle tek bağımlılıklarda yararlıdır.IOptionsSnapshot
Kapsamlı bir hizmettir ve nesne oluşturulurken seçeneklerinIOptionsSnapshot<T>
anlık görüntüsünü sağlar. Seçenekler anlık görüntüleri, geçici ve kapsamlı bağımlılıklarla kullanılmak üzere tasarlanmıştır.
Aşağıdaki kodda kullanılır IOptionsSnapshot<TOptions>.
public class TestSnapModel : PageModel
{
private readonly MyOptions _snapshotOptions;
public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
{
_snapshotOptions = snapshotOptionsAccessor.Value;
}
public ContentResult OnGet()
{
return Content($"Option1: {_snapshotOptions.Option1} \n" +
$"Option2: {_snapshotOptions.Option2}");
}
}
Aşağıdaki kod, şunlara bağlanan bir yapılandırma örneğini MyOptions
kaydeder:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Yukarıdaki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
IOptionsMonitor
Aşağıdaki kod, ile bağlanan bir yapılandırma örneğini MyOptions
kaydeder.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Aşağıdaki örnek şunu kullanır IOptionsMonitor<TOptions>:
public class TestMonitorModel : PageModel
{
private readonly IOptionsMonitor<MyOptions> _optionsDelegate;
public TestMonitorModel(IOptionsMonitor<MyOptions> optionsDelegate )
{
_optionsDelegate = optionsDelegate;
}
public ContentResult OnGet()
{
return Content($"Option1: {_optionsDelegate.CurrentValue.Option1} \n" +
$"Option2: {_optionsDelegate.CurrentValue.Option2}");
}
}
Yukarıdaki kodda varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
Adlandırılmış seçenekler IConfigureNamedOptions'ın kullanılmasını destekler
Adlandırılmış seçenekler:
- Birden çok yapılandırma bölümü aynı özelliklere bağlandığında kullanışlıdır.
- Büyük/küçük harfe duyarlıdır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
ve TopItem:Year
bağlamak TopItem:Month
için iki sınıf oluşturmak yerine, her bölüm için aşağıdaki sınıf kullanılır:
public class TopItemSettings
{
public const string Month = "Month";
public const string Year = "Year";
public string Name { get; set; }
public string Model { get; set; }
}
Aşağıdaki kod adlandırılmış seçenekleri yapılandırıyor:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<TopItemSettings>(TopItemSettings.Month,
Configuration.GetSection("TopItem:Month"));
services.Configure<TopItemSettings>(TopItemSettings.Year,
Configuration.GetSection("TopItem:Year"));
services.AddRazorPages();
}
Aşağıdaki kod adlandırılmış seçenekleri görüntüler:
public class TestNOModel : PageModel
{
private readonly TopItemSettings _monthTopItem;
private readonly TopItemSettings _yearTopItem;
public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
{
_monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
_yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
}
public ContentResult OnGet()
{
return Content($"Month:Name {_monthTopItem.Name} \n" +
$"Month:Model {_monthTopItem.Model} \n\n" +
$"Year:Name {_yearTopItem.Name} \n" +
$"Year:Model {_yearTopItem.Model} \n" );
}
}
Tüm seçenekler adlandırılmış örneklerdir. IConfigureOptions<TOptions>örnekleri, örneğini hedefleme Options.DefaultName
olarak değerlendirilir.string.Empty
IConfigureNamedOptions<TOptions> ayrıca uygular IConfigureOptions<TOptions>. varsayılan uygulamasının IOptionsFactory<TOptions> her birini uygun şekilde kullanmak için mantığı vardır. null
Adlandırılmış seçenek, belirli bir adlandırılmış örnek yerine tüm adlandırılmış örnekleri hedeflemek için kullanılır. ConfigureAll ve PostConfigureAll bu kuralı kullanın.
OptionsBuilder API'si
OptionsBuilder<TOptions> örnekleri yapılandırmak TOptions
için kullanılır. OptionsBuilder
sonraki tüm çağrılarda görüntülenmek yerine ilk AddOptions<TOptions>(string optionsName)
çağrının yalnızca tek bir parametresi olduğundan adlandırılmış seçeneklerin oluşturulmasını kolaylaştırır. Seçenek doğrulama ve ConfigureOptions
hizmet bağımlılıklarını kabul eden aşırı yüklemeler yalnızca aracılığıyla OptionsBuilder
kullanılabilir.
OptionsBuilder
, Seçenekler doğrulama bölümünde kullanılır.
Özel depo ekleme hakkında bilgi için bkz. Özel depo yapılandırmak için AddOptions kullanma.
Seçenekleri yapılandırmak için DI hizmetlerini kullanma
Hizmetlere bağımlılık eklemeden erişilirken seçenekler iki şekilde yapılandırılabilir:
üzerinde OptionsBuilder<TOptions>öğesine Configure bir yapılandırma temsilcisi geçirin.
OptionsBuilder<TOptions>
, seçenekleri yapılandırmak için beş adede kadar hizmetin kullanılmasına izin veren aşırı yüklemeler Configure sağlar:services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));
veya IConfigureNamedOptions<TOptions> uygulayan IConfigureOptions<TOptions> bir tür oluşturun ve türü hizmet olarak kaydedin.
Hizmet oluşturmak daha karmaşık olduğundan, öğesine bir yapılandırma temsilcisi Configuregeçirmenizi öneririz. Tür oluşturmak, çağırırken Configureçerçevenin yaptıklarına eşdeğerdir. Çağrısı Configure , belirtilen genel IConfigureNamedOptions<TOptions>hizmet türlerini kabul eden bir oluşturucuya sahip olan geçici bir genel kaydeder.
Seçenekler doğrulaması
Seçenekler doğrulaması, seçenek değerlerinin doğrulanmasına olanak tanır.
Aşağıdaki appsettings.json
dosyasını göz önünde bulundurun:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
Aşağıdaki sınıf yapılandırma bölümüne bağlanır "MyConfig"
ve birkaç DataAnnotations
kural uygular:
public class MyConfigOptions
{
public const string MyConfig = "MyConfig";
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")]
public string Key1 { get; set; }
[Range(0, 1000,
ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Key2 { get; set; }
public int Key3 { get; set; }
}
Aşağıdaki kod:
- Sınıfa bağlanan bir OptionsBuilder<TOptions> almak için
MyConfigOptions
çağrılarAddOptions. - kullanarak
DataAnnotations
doğrulamayı etkinleştirmek için çağrılarValidateDataAnnotations.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions<MyConfigOptions>()
.Bind(Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations();
services.AddControllersWithViews();
}
ValidateDataAnnotations
Uzantı yöntemi, Microsoft.Extensions.Options.DataAnnotations NuGet paketinde tanımlanır. SDK kullanan web uygulamaları için bu pakete Microsoft.NET.Sdk.Web
paylaşılan çerçeveden örtük olarak başvurulur.
Aşağıdaki kod yapılandırma değerlerini veya doğrulama hatalarını görüntüler:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IOptions<MyConfigOptions> _config;
public HomeController(IOptions<MyConfigOptions> config,
ILogger<HomeController> logger)
{
_config = config;
_logger = logger;
try
{
var configValue = _config.Value;
}
catch (OptionsValidationException ex)
{
foreach (var failure in ex.Failures)
{
_logger.LogError(failure);
}
}
}
public ContentResult Index()
{
string msg;
try
{
msg = $"Key1: {_config.Value.Key1} \n" +
$"Key2: {_config.Value.Key2} \n" +
$"Key3: {_config.Value.Key3}";
}
catch (OptionsValidationException optValEx)
{
return Content(optValEx.Message);
}
return Content(msg);
}
Aşağıdaki kod, temsilci kullanarak daha karmaşık bir doğrulama kuralı uygular:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions<MyConfigOptions>()
.Bind(Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.Key2 != 0)
{
return config.Key3 > config.Key2;
}
return true;
}, "Key3 must be > than Key2."); // Failure message.
services.AddControllersWithViews();
}
Karmaşık doğrulama için IValidateOptions
Aşağıdaki sınıf şunu uygular IValidateOptions<TOptions>:
public class MyConfigValidation : IValidateOptions<MyConfigOptions>
{
public MyConfigOptions _config { get; private set; }
public MyConfigValidation(IConfiguration config)
{
_config = config.GetSection(MyConfigOptions.MyConfig)
.Get<MyConfigOptions>();
}
public ValidateOptionsResult Validate(string name, MyConfigOptions options)
{
string vor=null;
var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$");
var match = rx.Match(options.Key1);
if (string.IsNullOrEmpty(match.Value))
{
vor = $"{options.Key1} doesn't match RegEx \n";
}
if ( options.Key2 < 0 || options.Key2 > 1000)
{
vor = $"{options.Key2} doesn't match Range 0 - 1000 \n";
}
if (_config.Key2 != default)
{
if(_config.Key3 <= _config.Key2)
{
vor += "Key3 must be > than Key2.";
}
}
if (vor != null)
{
return ValidateOptionsResult.Fail(vor);
}
return ValidateOptionsResult.Success;
}
}
IValidateOptions
, doğrulama kodunun sınıfın StartUp
dışına ve içine taşınmasını sağlar.
Yukarıdaki kod kullanılarak doğrulama aşağıdaki kodla etkinleştirilir Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfigOptions>(Configuration.GetSection(
MyConfigOptions.MyConfig));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions
<MyConfigOptions>, MyConfigValidation>());
services.AddControllersWithViews();
}
Yapılandırma sonrası seçenekler
ile IPostConfigureOptions<TOptions>yapılandırma sonrası ayarlayın. Yapılandırma sonrası, tüm IConfigureOptions<TOptions> yapılandırma gerçekleştikten sonra çalıştırılır:
services.PostConfigure<MyOptions>(myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
PostConfigure , adlandırılmış seçenekleri yapılandırma sonrası için kullanılabilir:
services.PostConfigure<MyOptions>("named_options_1", myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
Tüm yapılandırma örneklerini yapılandırma sonrası yapılandırmak için kullanın PostConfigureAll :
services.PostConfigureAll<MyOptions>(myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
Başlatma sırasında seçeneklere erişme
IOptions<TOptions> ve IOptionsMonitor<TOptions> içinde kullanılabilir Startup.Configure
, çünkü hizmetler yöntem yürütülmeden Configure
önce oluşturulur.
public void Configure(IApplicationBuilder app,
IOptionsMonitor<MyOptions> optionsAccessor)
{
var option1 = optionsAccessor.CurrentValue.Option1;
}
veya IOptionsMonitor<TOptions> içinde Startup.ConfigureServices
kullanmayınIOptions<TOptions>. Hizmet kayıtlarının sıralanması nedeniyle tutarsız bir seçenek durumu olabilir.
Options.ConfigurationExtensions NuGet paketi
Microsoft.Extensions.Options.ConfigurationExtensions paketine ASP.NET Core uygulamalarında örtük olarak başvurulur.
ASP.NET Core