ASP.NET Core'da seçenek deseni
, Kirk Larkabağı ve Rick Anderson.
Seçenekler stili, ilişkili ayarlar gruplarına kesin olarak belirlenmiş erişim sağlamak için sınıfları kullanır. Yapılandırma ayarları senaryo tarafından ayrı sınıflara ayrılmışsa, uygulama iki önemli yazılım mühendisliği ilkelerine uyar:
- Yapılandırma ayarlarına bağlı olan arabirim ayırma ilkesi (ISS) veya kapsülleme: senaryolar (sınıflar) yalnızca kullandıkları yapılandırma ayarlarına bağlıdır.
- kaygıları ayrımı: uygulamanın farklı parçaları için Ayarlar birbirlerine bağımlı değil veya birbirlerine bağlanmış değil.
Seçenekler Ayrıca yapılandırma verilerini doğrulamaya yönelik bir mekanizma sağlar. Daha fazla bilgi için Seçenekler doğrulama bölümüne bakın.
Bu konu, ASP.NET Core seçenekler düzeniyle ilgili bilgiler sağlar. Konsol uygulamalarında seçenekler deseninin kullanımı hakkında bilgi için bkz. .net 'Teki seçenekler stili.
Örnek kodu görüntüleme veya indirme (nasıl indirileceği)
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 sınıfı PositionOptions oluşturun:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Options sınıfı:
- Genel parametresiz oluşturucu ile soyut olmayan olmalıdır.
- Türün tüm genel okuma-yazma özellikleri bağımlıdır.
- Alanlar bağlı değildir. Yukarıdaki
Positionkodda, bağlı değildir.Positionözelliği kullanılır, böylece"Position"sınıfı bir yapılandırma sağlayıcısına bağlarken dizenin uygulamada sabit koda sahip olması gerek yoktur.
Aşağıdaki kod:
- Sınıfını bölümüne bağlamak için ConfigurationBinder.Bind'i
PositionOptionsPositionarar. - Yapılandırma
Positionverilerini 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}");
}
}
Önceki 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> kullanmaktan daha kullanışlı ConfigurationBinder.Bind olabilir. Aşağıdaki kod, sınıfıyla nasıl ConfigurationBinder.Get<T> kullanabileceğini PositionOptions gösterir:
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}");
}
}
Önceki kodda, varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
- seçenekler deseni _ kullanılırken alternatif bir yaklaşım bölümü bağlamak ve bağımlılık ekleme hizmeti
Positionkapsayıcısı eklemektir. Aşağıdaki kodda,PositionOptionsile hizmet kapsayıcısı eklenir ve <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure_> yapılandırmaya bağlıdı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, yukarıdaki 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 okunmaz. Uygulama başlatıldıktan sonra değişiklikleri okumak için IOptionsSnapshot kullanın.
Seçenekler arabirimleri
- Şunları desteklemez:
- Uygulama başladıktan sonra yapılandırma verilerinin okunması.
- Adlandırılmış seçenekler
- Tek bir olarak kaydedilir ve herhangi bir hizmet ömrüneeklenebilir.
- Seçeneklerin her istekte yeniden hesaplanması gereken senaryolarda faydalıdır. Daha fazla bilgi için bkz. güncelleştirilmiş verileri okumak Için ıoptionssnapshot kullanma.
- Kapsamlı olarak kaydedilir ve bu nedenle tek bir hizmete eklenemez.
- Adlandırılmış seçenekleri destekler
- , Seçenekleri almak ve örnekler için seçenek bildirimlerini yönetmek için kullanılır
TOptions. - Tek bir olarak kaydedilir ve herhangi bir hizmet ömrüneeklenebilir.
- Desteklememektedir
- Değişiklik bildirimleri
- adlandırılmış seçenekler
- Yeniden yüklenebilir yapılandırma
- Seçmeli seçenekler geçersiz kılma ( IOptionsMonitorCache<TOptions> )
Yapılandırma sonrası senaryolar, tüm yapılandırma oluştuktan sonra ayarları veya değiştirme seçeneklerini etkinleştirir IConfigureOptions<TOptions> .
IOptionsFactory<TOptions> yeni seçenek örnekleri oluşturmaktan sorumludur. Tek bir metodu vardır Create . Varsayılan uygulama tüm kayıtlı IConfigureOptions<TOptions> ve IPostConfigureOptions<TOptions> sonrasında tüm yapılandırmaları çalıştırır ve sonrasında yapılandırma sonrası. Ve arasında ayrım yapar ve IConfigureNamedOptions<TOptions> IConfigureOptions<TOptions> yalnızca uygun arabirimi çağırır.
IOptionsMonitorCache<TOptions> , IOptionsMonitor<TOptions> örnekleri önbelleğe almak için tarafından kullanılır TOptions . , IOptionsMonitorCache<TOptions> Değer yeniden hesaplanabilmesi için izleyici içindeki seçenek örneklerini geçersiz kılar ( TryRemove ). Değerler ile el ile tanıtılamaz TryAdd . ClearYöntemi, 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 ıoptionssnapshot kullanın
IOptionsSnapshot<TOptions>' Yi kullanarak, her erişildiğinde ve isteğin ömrü boyunca önbelleğe alındığında Seçenekler her istek için bir kez hesaplanır. Güncelleştirilmiş yapılandırma değerlerini okumayı destekleyen yapılandırma sağlayıcıları kullanılırken, yapılandırma değişiklikleri uygulama başladıktan sonra okundu.
Ve arasındaki fark IOptionsMonitor IOptionsSnapshot şudur:
IOptionsMonitor, özellikle tek bağımlılıklarda yararlı olan herhangi bir zamanda geçerli seçenek değerlerini alan bir tek hizmettir .IOptionsSnapshotkapsamlı bir hizmettir ve nesnenin oluşturulduğu sırada seçeneklerin anlık görüntüsünü sağlarIOptionsSnapshot<T>. 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 kod kullanı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, ' a bağlanan bir yapılandırma örneği kaydeder MyOptions :
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şladıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okundu.
Ioptionsmonitor
Aşağıdaki kod, ' a bağlanan bir yapılandırma örneği kaydeder MyOptions .
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şladıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunurdur.
IController Enamedooptıons kullanarak adlandırılmış seçenekler desteği
Adlandırılmış seçenekler:
- Aynı özelliklere birden çok yapılandırma bölümü bağlandığı zaman faydalıdır.
- Büyük/küçük harfe duyarlıdır.
Aşağıdaki dosyayı göz önünde bulundurun appsettings.json :
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
Ve bağlamak için iki sınıf oluşturmak yerine TopItem:Month TopItem:Year , 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ır:
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österir:
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> örnekler, örneği hedefleme olarak değerlendirilir Options.DefaultName string.Empty . IConfigureNamedOptions<TOptions> Ayrıca uygular IConfigureOptions<TOptions> . Varsayılan uygulamasının, her birini IOptionsFactory<TOptions> uygun şekilde kullanma mantığı vardır. nullAdlandı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.
Seçenekno Oluşturucu API 'SI
OptionsBuilder<TOptions> örnekleri yapılandırmak için kullanılır TOptions . OptionsBuilder adlandırılmış seçenekleri, sonraki çağrıların tümünde olmak yerine ilk çağrının tek bir parametresi olacak şekilde oluşturmayı kolaylaştırır AddOptions<TOptions>(string optionsName) . Seçenekler doğrulaması ve ConfigureOptions hizmet bağımlılıklarını kabul eden aşırı yüklemeler yalnızca aracılığıyla kullanılabilir OptionsBuilder .
OptionsBuilderSeçenekler doğrulama bölümünde kullanılır.
Özel depo ekleme hakkında bilgi için bkz. özel depoyu yapılandırmak Için Addoçen'lar kullanma .
Ayarları yapılandırmak için dı hizmetlerini kullanma
Seçenekleri iki şekilde yapılandırırken, hizmetlere bağımlılık ekleme işleminden erişilebilir:
Options Builder <TOptions> 'da yapılandırmak için bir yapılandırma temsilcisi geçirin.
OptionsBuilder<TOptions>, seçenekleri yapılandırmak için en fazla beş hizmet kullanılmasına izin veren yapılandırma yüklerini 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 uygulayan bir tür oluşturun IConfigureOptions<TOptions> IConfigureNamedOptions<TOptions> ve türü bir hizmet olarak kaydedin.
Bir hizmetin oluşturulması daha karmaşık olduğundan, yapılandırmakiçin bir yapılandırma temsilcisinin geçirilmesini öneririz. Bir tür oluşturmak,, Yapılandırçağrılırken çerçevenin yaptığı işe eşdeğerdir. Yapılandırma çağrısı IConfigureNamedOptions<TOptions> , belirtilen genel hizmet türlerini kabul eden bir oluşturucuya sahip olan geçici bir genel kayıt kaydeder.
Seçenekler doğrulaması
Seçenekler doğrulaması seçenek değerlerinin doğrulanmasını sağlar.
Aşağıdaki dosyayı göz önünde bulundurun appsettings.json :
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
Aşağıdaki sınıf yapılandırma bölümüne bağlamak için kullanılı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:
- AddOptionsSınıfına bağlanan bir seçenekoluşturucu Oluşturucu <TOptions> almak için çağırır
MyConfigOptions. - ValidateDataAnnotationsKullanarak doğrulamayı etkinleştirmek için çağırır
DataAnnotations.
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();
ValidateDataAnnotationsuzantı yöntemi, Microsoft. Extensions. Options. dataaçıklamalarda NuGet paketinde tanımlanmıştır. SDK kullanan Web uygulamaları için Microsoft.NET.Sdk.Web Bu pakete, dolaylı olarak paylaşılan çerçeveden 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, bir 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();
Karmaşık doğrulama için ıvalidateoptions
Aşağıdaki sınıf şunları 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 kodunu StartUp bir sınıfa ve sınıfına taşımaya izin vermez.
Önceki kodu kullanarak, doğrulama program. cs ' de aşağıdaki kodla etkinleştirilir:
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();
Yapılandırma sonrası seçenekler
Yapılandırma sonrası ' i ayarlayın IPostConfigureOptions<TOptions> . Yapılandırma sonrası tüm IConfigureOptions<TOptions> yapılandırma oluştuktan sonra çalışı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ırmak 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 PostConfigureAll yapılandırma örneklerini post-configure için kullanın:
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";
});
Rick Larkin ve Rick Anderson tarafından.
Seçenekler düzeni, ilgili ayar gruplarına kesin olarak türü kesin olarak yazarak erişim sağlamak için sınıfları kullanır. Yapılandırma ayarları senaryoya göre ayrı sınıflara yalıtılmışsa, uygulama iki önemli yazılım mühendisliği ilkesine uyar:
- Arabirim Ayrımı İlkesi (ISS)veya Kapsülleme: Yapılandırma ayarlarına bağlı senaryolar (sınıflar) yalnızca kendi kullanımları yapılandırma ayarlarına bağlıdır.
- Endişelerin Ayrımı:Ayarlar farklı bölümlerinin birbirine bağımlı veya birbirine bağlı olmadığını varsayabilirsiniz.
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 konuda, verilerde seçenekler deseni hakkında ASP.NET Core. Konsol uygulamalarına seçenekler desenini kullanma hakkında bilgi için bkz. .NET'te seçenekler deseni.
Örnek kodu görüntüleme veya indirme ( nasılindir)
Bağlama hiyerarşik yapılandırması
İlgili yapılandırma değerlerini okumak için tercih edilen yol, Seçenekler modelinikullanmaktır. Örneğin, aşağıdaki yapılandırma değerlerini okumak için:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Aşağıdaki sınıfı oluşturun PositionOptions :
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; }
public string Name { get; set; }
}
Seçenekler sınıfı:
- Ortak parametresiz bir oluşturucuya sahip olmayan Özet olmamalıdır.
- Türün tüm genel okuma-yazma özellikleri bağlanır.
- Alanlar bağlanmadı . Yukarıdaki kodda,
Positionbağlantılı değildir.PositionÖzelliği,"Position"sınıfı bir yapılandırma sağlayıcısına bağlarken, dizenin uygulamada sabit kodlanmış olması gerekmez.
Aşağıdaki kod:
- Sınıfı bölümüne bağlamak için Configurationciltçi. Bind ' i çağırır
PositionOptionsPosition. PositionYapılandırma verilerini 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şladıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunurdur.
ConfigurationBinder.Get<T> belirtilen türü bağlar ve döndürür. ConfigurationBinder.Get<T> , kullanmaktan daha uygun olabilir ConfigurationBinder.Bind . Aşağıdaki kod, sınıfıyla birlikte nasıl kullanılacağını gösterir ConfigurationBinder.Get<T> PositionOptions :
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şladıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunurdur.
*Seçenek deseninin _ 'i kullanılırken alternatif bir yaklaşım, Position bölümü bağlamak ve bağımlılık ekleme hizmeti kapsayıcısınaeklemektir. Aşağıdaki kodda, PositionOptions ile hizmet kapsayıcısına eklenir <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure_> ve yapılandırmaya bağlanır:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<PositionOptions>(Configuration.GetSection(
PositionOptions.Position));
services.AddRazorPages();
}
Önceki kodu kullanarak, aşağıdaki kod 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şladıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunamaz. Uygulama başladıktan sonra değişiklikleri okumak için ıoptionssnapshotkullanın.
Seçenekler arabirimleri
- Şunları desteklemez:
- Uygulama başlatıldıktan sonra yapılandırma verilerini okuma.
- Adlandırılmış seçenekler
- Bir Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne edilebilir.
- Seçeneklerin her istekte yeniden yorumlandı olması gereken senaryolarda kullanışlıdır. Daha fazla bilgi için bkz. Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma.
- Kapsamı Kapsamlı olarak kaydedilir ve bu nedenle bir Singleton hizmetine ekleme olamaz.
- Adlandırılmış seçenekleri destekler
- Örnekler için seçenekleri almak ve seçenek bildirimlerini yönetmek
TOptionsiçin kullanılır. - Bir Singleton olarak kaydedilir ve herhangi bir hizmet ömrüne edilebilir.
- Destekle -yen:
- Bildirimleri değiştirme
- Adlandırılmış seçenekler
- Yeniden yüklenebilir yapılandırma
- Seçmeli seçenekleri geçersiz kılınma ( IOptionsMonitorCache<TOptions> )
Yapılandırma sonrası senaryolar, tüm yapılandırmalar tamam olduktan sonra seçeneklerin ayar IConfigureOptions<TOptions> veya değiştirilmesini sağlar.
IOptionsFactory<TOptions> , yeni seçenek örnekleri oluşturmakla sorumludur. Tek bir yöntemi Create vardır. Varsayılan uygulama tüm kayıtlı yapılandırmaları alır ve önce tüm IConfigureOptions<TOptions> IPostConfigureOptions<TOptions> yapılandırmaları çalıştırır ve ardından yapılandırma sonrası gelir. ile arasında ayrım IConfigureNamedOptions<TOptions> yapmak için yalnızca uygun arabirimi IConfigureOptions<TOptions> çağıran bir uygulamadır.
IOptionsMonitorCache<TOptions> , örnekleri IOptionsMonitor<TOptions> önbelleğe etmek TOptions için tarafından kullanılır. , IOptionsMonitorCache<TOptions> değerin yeniden sayılacak şekilde izleyicide seçenekler örneklerini geçersiz hale gelir ( TryRemove ). Değerler ile el ile TryAdd tanıtılabilir. yöntemi, Clear tüm adlandırılmış örneklerin isteğe bağlı olarak yeniden oluşturulması gerektiği durumlarda kullanılır.
Güncelleştirilmiş verileri okumak için IOptionsSnapshot kullanma
kullanılarak, seçenekler isteğin yaşam süresi boyunca erişilen ve önbelleğe IOptionsSnapshot<TOptions> alınan istek başına bir kez hesaplanır. Yapılandırmada yapılan değişiklikler, güncelleştirilmiş yapılandırma değerlerini okumayı destekleyen yapılandırma sağlayıcıları kullanılırken uygulama başladıktan sonra okunur.
ile arasındaki IOptionsMonitor fark IOptionsSnapshot şudur:
IOptionsMonitor, geçerli seçenek değerlerini her zaman alan ve özellikle tekli bağımlılıklarda yararlı olan tekli bir hizmettir.IOptionsSnapshotkapsamlı bir hizmettir ve nesnenin oluşturulurken seçeneklerin anlıkIOptionsSnapshot<T>görüntüsünü sağlar. Seçenekler anlık görüntüleri, geçici ve kapsamlı bağımlılıklarla kullanım için tasarlanmıştır.
Aşağıdaki kod IOptionsSnapshot<TOptions> kullanır.
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, aşağıdakilere bağlanan bir MyOptions yapılandırma örneğini kaydettirmektedir:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Önceki kodda, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
IOptionsMonitor
Aşağıdaki kod, bağlaması yapılan bir yapılandırma MyOptions örneğini kaydettirmektedir.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Aşağıdaki örnekte IOptionsMonitor<TOptions> kullanır:
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}");
}
}
Önceki kodda, varsayılan olarak, uygulama başlatıldıktan sonra JSON yapılandırma dosyasında yapılan değişiklikler okunur.
IConfigureNamedOptions kullanarak adlandırılmış seçenekler desteği
Adlandırılmış seçenekler:
- Birden çok yapılandırma bölümü aynı özelliklere bağlanacak olduğunda yararlıdır.
- Büyük/büyük/büyük harfe duyarlıdır.
Aşağıdaki dosyayı göz appsettings.json önünde bulun:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
ve bağlamak için iki sınıf oluşturmak TopItem:Month TopItem:Year 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> örnekler, örneği hedefleme olarak kabul Options.DefaultName edilir ve bu da string.Empty olur. IConfigureNamedOptions<TOptions> ayrıca , 'i de uygulayan IConfigureOptions<TOptions> bir uygulamadır. Varsayılan uygulamasının her IOptionsFactory<TOptions> biri uygun şekilde kullanma mantığı vardır. Adlandırılmış null 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ünmek yerine ilk çağrının yalnızca tek bir parametresi olduğu için AddOptions<TOptions>(string optionsName) adlandırılmış seçeneklerin oluşturulmasını kolaylaştırıyor. 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. AddOptions kullanarak özel depo yapılandırma.
Seçenekleri yapılandırmak için DI hizmetlerini kullanma
Seçenekler iki şekilde yapılandırırken hizmetlere bağımlılık eklemeden erişilebilir:
Bir yapılandırma temsilcisini OptionsBuilder'da Yapılandır'a ilenin. <TOptions>
OptionsBuilder<TOptions>, seçenekleri yapılandırmak için en fazla beş hizmet kullanımına izin veren Yapılandır aşırı yüklemelerini 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 uygulayan bir IConfigureOptions<TOptions> tür oluşturun ve türü hizmet olarak IConfigureNamedOptions<TOptions> kaydedin.
Bir hizmet oluşturmak daha karmaşık olduğu için yapılandırmatemsilcisini Yapılandırma'ya geçirmenizi öneririz. Tür oluşturmak, Yapılandır'ı çağıran çerçevenin ne yaptığına eşdeğerdir. Configure çağrısı, belirtilen genel hizmet türlerini kabul IConfigureNamedOptions<TOptions> eden bir oluşturucuya sahip olan geçici bir genel 'i kaydettirmektedir.
Seçenek doğrulama
Seçenek doğrulaması, seçenek değerlerinin doğrulanmasına olanak sağlar.
Aşağıdaki dosyayı göz appsettings.json önünde bulun:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
Aşağıdaki sınıf yapılandırma bölümüne "MyConfig" bağlar ve birkaç kural DataAnnotations 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ıfına AddOptions bağlı bir <TOptions> OptionsBuilder almak için
MyConfigOptionsçağrıları. - kullanarak ValidateDataAnnotations doğrulamayı etkinleştirmek için
DataAnnotationsçağrıları.
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();
}
Uzantı ValidateDataAnnotations yöntemi, Microsoft.Extensions.Options.DataAnnotations NuGet tanımlanır. SDK kullanan web uygulamaları Microsoft.NET.Sdk.Web için bu pakete paylaşılan çerçeveden örtülü olarak başvurılır.
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 IValidateOptions<TOptions> uygulayan:
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 ve dışından StartUp bir sınıfa taşınmasını sağlar.
Yukarıdaki kod kullanılarak, içinde aşağıdaki Startup.ConfigureServices kodla doğrulama etkinleştirilir:
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 yapılandırma sonrası IPostConfigureOptions<TOptions> ayarlama. Yapılandırma sonrası tüm yapılandırmalar IConfigureOptions<TOptions> olduktan sonra çalışı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 PostConfigureAll yapılandırma örneklerini post-configure için kullanın:
services.PostConfigureAll<MyOptions>(myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
Başlatma sırasında seçeneklere erişme
IOptions<TOptions> ve ' IOptionsMonitor<TOptions> de Startup.Configure , hizmetler Yöntem yürütmeden önce oluşturulduğundan ' de kullanılabilir Configure .
public void Configure(IApplicationBuilder app,
IOptionsMonitor<MyOptions> optionsAccessor)
{
var option1 = optionsAccessor.CurrentValue.Option1;
}
IOptions<TOptions>Veya içinde kullanmayın IOptionsMonitor<TOptions> Startup.ConfigureServices . Hizmet kayıtlarının sıralaması nedeniyle tutarsız bir seçenek durumu var olabilir.
Options. configurationextensions NuGet paketi
Microsoft. Extensions. Options. configurationextensions paketine ASP.NET Core uygulamalarında örtük olarak başvurulur.