Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Note
Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.
Warning
A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .
Az opciós minta osztályok használatával erősen típusos hozzáférést biztosít a kapcsolódó beállítások csoportjaihoz. Ha a konfigurációs beállításokat forgatókönyvek szerint külön osztályokba különítjük el, az alkalmazás két fontos szoftvermérnöki alapelvnek felel meg:
-
Encapsulation:
- A konfigurációs beállításoktól függő osztályok csak az általuk használt konfigurációs beállításoktól függnek.
-
Az aggodalmak elkülönítése:
- Az alkalmazás különböző részeinek beállításai nem függenek egymástól, és nincsenek összekapcsolva.
A beállítások emellett a konfigurációs adatok ellenőrzésére szolgáló mechanizmust is biztosítanak. További információt a Beállítások érvényesítési szakaszában talál.
Ez a cikk a ASP.NET Core beállítási mintájáról nyújt tájékoztatást. A beállítási minta konzolalkalmazásokban való használatáról további információt a .NET Beállítások mintája című témakörben talál.
Hierarchikus konfiguráció kötése
A kapcsolódó konfigurációs értékek olvasásának elsődleges módja a beállítási minta használata. Például a következő konfigurációs értékek olvasásához:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Hozza létre a következő PositionOptions osztályt:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Egy beállításosztály:
- Nem absztraktnak kell lennie.
- Olyan nyilvános írási-olvasási tulajdonsággal rendelkezik, amelynek megfelelő elemei vannak megkötve a konfigurációban.
- Olvasási-írási tulajdonságai a konfigurációban lévő bejegyzésekhez vannak kötve.
-
Nem rendelkezik mezői megkötésével. Az előző kódban a
Positionnincs kötés alatt. APositionmező célja, hogy ne kelljen a"Position"sztringet kézzel kódolni az alkalmazásban, amikor az osztályt egy konfigurációs szolgáltatóhoz kötjük.
A következő kód:
- A ConfigurationBinder.Bind meghívásával köti az osztályt
PositionOptionsaPositionszakaszhoz. - Megjeleníti a
Positionkonfigurációs adatokat.
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
ConfigurationBinder.Get<T> köti és visszaadja a megadott típust.
ConfigurationBinder.Get<T> lehet, hogy kényelmesebb, mint a használata ConfigurationBinder.Bind. Az alábbi kód bemutatja, hogyan használható ConfigurationBinder.Get<T> az PositionOptions osztály:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
A kötés lehetővé teszi egy absztrakt osztály összefűzését is. Vegye figyelembe a következő kódot, amely az absztrakt osztályt SomethingWithANamehasználja:
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 következő kód a NameTitleOptions konfigurációs értékeket jeleníti meg:
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 Bind hívások kevésbé szigorúak, mint a Get<> hívások.
-
Bindlehetővé teszi egy absztrakt megvalósítását. -
Get<>-nak/nak kell saját magának példányt létrehoznia.
A beállítások mintája
A beállítási minta használatakor alternatív módszer a szakasz kötése Position és hozzáadása a függőséginjektálási szolgáltatás tárolóhoz. A következő kódban PositionOptions hozzáadásra kerül a szolgáltatástárolóhoz Configure-sel és konfigurációhoz kötve:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Az előző kód használatával a következő kód felolvassa a pozícióbeállításokat:
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}");
}
}
Az előző kódban az alkalmazás elindítása után a JSON-konfigurációs fájl módosításai nem lesznek beolvasva. Az alkalmazás elindítása utáni módosítások olvasásához használja az IOptionsSnapshot parancsot.
Beállítási felületek
-
Nem támogatja a következőt:
- A konfigurációs adatok olvasása az alkalmazás elindítása után.
- Elnevezett beállítások
- Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Olyan helyzetekben hasznos, ahol a beállításokat minden kérésnél újra kell cserélni. További információ: Az IOptionsSnapshot használata a frissített adatok olvasásához.
- Hatókörként van regisztrálva, ezért nem adhatók be egy Singleton-szolgáltatásba.
- Támogatja a névvel ellátott beállításokat
- A beállítási lehetőségek lekérésére és a
TOptionspéldányok beállításainak kezelésére szolgál. - Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Supports:
- Értesítések módosítása
- elnevezett beállítások
- Újratölthető konfiguráció
- Szelektív beállítások érvénytelenítése (IOptionsMonitorCache<TOptions>)
A konfiguráció utáni forgatókönyvek lehetővé teszik a beállítások beállítását vagy módosítását az összes IConfigureOptions<TOptions> konfiguráció után.
IOptionsFactory<TOptions> új beállításpéldányok létrehozásáért felelős. Egyetlen Create metódussal rendelkezik. Az alapértelmezett implementáció összegyűjti az összes regisztrált IConfigureOptions<TOptions> és IPostConfigureOptions<TOptions>, először futtatja az összes konfigurációt, majd végrehajtja a konfiguráció utáni műveleteket. Megkülönbözteti IConfigureNamedOptions<TOptions> és IConfigureOptions<TOptions> között, és csak a megfelelő felületet hívja meg.
IOptionsMonitorCache<TOptions>-t a IOptionsMonitor<TOptions> használja a TOptions példányok gyorsítótárazására. Az IOptionsMonitorCache<TOptions> érvényteleníti a figyelőben lévő beállításpéldányokat, hogy az értéket újraszámítsák TryRemove. Az értékek manuálisan is bevezethetők a TryAdd. A Clear metódus akkor használatos, ha az összes elnevezett példányt igény szerint újra létre kell hozni.
Frissített adatok olvasása az IOptionsSnapshot használatával
IOptionsSnapshot<TOptions> használata:
- A rendszer kérésenként egyszer számítja ki a beállításokat, amikor a kérés teljes élettartama alatt hozzáférnek és gyorsítótáraznak.
- Jelentős teljesítménycsökkenést okozhat, mivel egy rétegezett szolgáltatás , amely kérésenként újraszámításra kerül. További információkért tekintse meg ezt a GitHub-problémát , és javítsa a konfigurációs kötés teljesítményét.
- A konfiguráció módosításai az alkalmazás elindítása után jelennek meg, amikor olyan konfigurációszolgáltatókat használ, amelyek támogatják a frissített konfigurációs értékek olvasását.
A különbség a következők között IOptionsMonitorIOptionsSnapshot van:
-
IOptionsMonitorEgy Singleton-szolgáltatás , amely bármikor lekéri az aktuális beállításértékeket, ami különösen hasznos az egyszeri függőségekben. -
IOptionsSnapshotegy hatókörű szolgáltatás, és azIOptionsSnapshot<T>objektum létrehozásának időpontjában pillanatképet nyújt a lehetőségekről. A beállítási pillanatképek átmeneti és hatókörű függőségekhez használhatók.
Az alábbi kód a következőt használja 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}");
}
}
Az alábbi kód regisztrál egy konfigurációs példányt, amely a következőhöz kötődik: MyOptions.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Az előző kódban a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után beolvasásra kerülnek.
IOptionsMonitor
Az alábbi kód regisztrál egy konfigurációs példányt, amelyhez MyOptions kapcsolódik.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Az alábbi példa IOptionsMonitor<TOptions>használ:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
Egyéni kulcsnév megadása konfigurációs tulajdonsághoz a következő használatával: ConfigurationKeyName
Alapértelmezés szerint a beállításosztály tulajdonságnevét használja a rendszer a konfigurációs forrás kulcsneveként. Ha a tulajdonság neve Title, akkor a konfigurációban a kulcs neve is Title.
A nevek megkülönböztetésekor az ConfigurationKeyName attribútum használatával megadhatja a kulcs nevét a konfigurációs forrásban. Ezzel a technikával a konfiguráció egyik tulajdonságát egy másik névvel rendelheti hozzá a kódhoz.
Ez akkor hasznos, ha a konfigurációs forrás tulajdonságneve nem érvényes C#-azonosító, vagy ha más nevet szeretne használni a kódban.
Vegyük például a következő beállításosztályt:
public class PositionOptionsWithConfigurationKeyName
{
public const string Position = "Position";
[ConfigurationKeyName("position-title")]
public string Title { get; set; } = string.Empty;
[ConfigurationKeyName("position-name")]
public string Name { get; set; } = string.Empty;
}
A(z) Title és Name osztály tulajdonságai a position-title és position-name elemekhez a következő appsettings.json fájlban vannak kötve.
{
"Position": {
"position-title": "Editor",
"position-name": "Joe Smith"
}
}
Az elnevezett beállítások támogatása az IConfigureNamedOptions használatával
Elnevezett beállítások:
- Akkor hasznos, ha több konfigurációs szakasz is ugyanahhoz a tulajdonsághoz kapcsolódik.
- Megkülönbözteti a kis- és nagybetűket.
Fontolja meg a következő appsettings.json fájlt:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
Ahelyett, hogy a TopItem:Month és TopItem:Year összekapcsolásához két osztályt hozna létre, az alábbi osztály használatos az egyes szakaszokhoz:
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 következő kód konfigurálja a névvel ellátott beállításokat:
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();
Az alábbi kód a névvel ellátott beállításokat jeleníti meg:
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" );
}
}
Minden opció egy nevesített példány.
IConfigureOptions<TOptions> példányokat úgy kezelik, mint amelyek a Options.DefaultName példányt célozzák meg, ami string.Empty.
IConfigureNamedOptions<TOptions> is megvalósítja IConfigureOptions<TOptions>. Az alapértelmezett implementáció logikát tartalmaz, hogy az egyes elemeket megfelelően használja. A null névvel ellátott beállítás az összes elnevezett példányt megcélozza egy adott elnevezett példány helyett.
ConfigureAll és PostConfigureAll használja ezt az egyezményt.
OptionsBuilder API
OptionsBuilder<TOptions> példányok konfigurálására van használva TOptions.
OptionsBuilder Egyszerűbbé teszi az elnevezett beállítások létrehozását, mivel ez csak egy paraméter a kezdeti AddOptions<TOptions>(string optionsName) híváshoz, ahelyett, hogy az összes későbbi hívásban megjelenne. A beállítások érvényesítése és a ConfigureOptions szolgáltatásfüggőségeket elfogadó túlterhelések csak a OptionsBuilder elérhetők.
OptionsBuildera Beállítások érvényesítési szakaszában használható.
Lásd: Az AddOptions használata az egyéni tárház konfigurálásához az egyéni tárház hozzáadásával kapcsolatos információkért.
Beállítások konfigurálása a DI-szolgáltatások használatával
A szolgáltatások a függőséginjektálásból érhetők el, a beállítások kétféleképpen konfigurálhatók:
Adjon át egy konfigurációs delegátumot a ConfigureOptionsBuilder<TOptions> parancsnak.
OptionsBuilder<TOptions>olyan túlterheléseket Configure biztosít, amelyek legfeljebb öt szolgáltatás használatát teszik lehetővé a beállítások konfigurálásához: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));Hozzon létre egy típust, amely megvalósítja IConfigureOptions<TOptions> vagy IConfigureNamedOptions<TOptions>, és regisztrálja a típust szolgáltatásként.
Javasoljuk, hogy adjon át egy konfigurációs delegáltat Configure-nek, mivel a szolgáltatás létrehozása összetettebb. A típus létrehozása egyenértékű azzal, amit a keretrendszer a híváskor Configurevégez. A hívás Configure egy átmeneti általánost IConfigureNamedOptions<TOptions>regisztrál, amelynek konstruktora elfogadja a megadott általános szolgáltatástípusokat.
Beállítások érvényesítése
A beállítások érvényesítése lehetővé teszi a beállításértékek érvényesítését.
Fontolja meg a következő appsettings.json fájlt:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
A következő osztály a konfigurációs szakaszhoz való kötésre "MyConfig" szolgál, és néhány DataAnnotations szabályt alkalmaz:
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 következő kód:
- Hívásokat AddOptions az OptionsBuilder<TOptions> megszerzéséhez, amely az
MyConfigOptionsosztályhoz kötődik. - Az érvényesítés engedélyezésére hívja meg a ValidateDataAnnotations a
DataAnnotationshasználatával.
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();
A ValidateDataAnnotations bővítménymetódus a Microsoft.Extensions.Options.DataAnnotations NuGet-csomagban van definiálva. Az SDK-t használó Microsoft.NET.Sdk.Web webalkalmazások esetében a csomagra implicit módon hivatkozik a megosztott keretrendszer.
Az alábbi kód a konfigurációs értékeket vagy az érvényesítési hibákat jeleníti meg:
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 következő kód egy összetettebb érvényesítési szabályt alkalmaz meghatalmazott használatával:
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> és IValidatableObject
A következő osztály implementálja 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 lehetővé teszi az érvényesítési kód Program.cs-ből való áthelyezését egy osztályba.
Az előző kód használatával az Program.cs ellenőrzés a következő kóddal van engedélyezve.
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();
A beállítások érvényesítése a következőt is támogatja IValidatableObject: Egy osztály osztályszintű ellenőrzésének végrehajtása magában az osztályban:
- Implementálja az interfészt
IValidatableObjectés annak metódusát Validate az osztályon belül. -
ValidateDataAnnotations hívása
Program.cs.
ValidateOnStart
A TOption példány első létrehozásakor fut a beállítások érvényesítése. Ez például azt jelenti, hogy amikor egy kérelemfolyamatban először férnek hozzá IOptionsSnapshot<TOptions>.Value-hoz, vagy amikor IOptionsMonitor<TOptions>.Get(string)-ot hívnak meg a meglévő beállításokon. A beállítások újbóli betöltése után az érvényesítés újra lefut. A ASP.NET Core-futtatókörnyezet a OptionsCache<TOptions> létrehozás után gyorsítótárazza a beállításpéldányt.
A beállítások ellenőrzésének azonnali futtatásához, az alkalmazás indításakor hívja fel a következőt ValidateOnStart<TOptions>(OptionsBuilder<TOptions>)Program.cs:
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.ValidateOnStart();
Beállítások a konfigurációt követően
Utókonfiguráció beállítása a következővel IPostConfigureOptions<TOptions>. A konfiguráció utáni futtatás az összes IConfigureOptions<TOptions> konfiguráció után megtörténik:
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 a névvel ellátott beállítások utólagos konfigurálásához érhető el:
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();
A PostConfigureAll eszközt az összes konfigurációs példány utólagos konfigurálására használja:
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";
});
Hozzáférési beállítások a következőben: Program.cs
Az IOptions<TOptions> vagy IOptionsMonitor<TOptions> eléréséhez a Program.cs nevű helyen, hívja a GetRequiredService számot a következőhöz WebApplication.Services:
var app = builder.Build();
var option1 = app.Services.GetRequiredService<IOptionsMonitor<MyOptions>>()
.CurrentValue.Option1;
További erőforrások
Az opciós minta osztályok használatával erősen típusos hozzáférést biztosít a kapcsolódó beállítások csoportjaihoz. Ha a konfigurációs beállításokat forgatókönyvek szerint külön osztályokba különítjük el, az alkalmazás két fontos szoftvermérnöki alapelvnek felel meg:
-
Encapsulation:
- A konfigurációs beállításoktól függő osztályok csak az általuk használt konfigurációs beállításoktól függnek.
-
Az aggodalmak elkülönítése:
- Az alkalmazás különböző részeinek beállításai nem függenek egymástól, és nincsenek összekapcsolva.
A beállítások emellett a konfigurációs adatok ellenőrzésére szolgáló mechanizmust is biztosítanak. További információt a Beállítások érvényesítési szakaszában talál.
Ez a cikk a ASP.NET Core beállítási mintájáról nyújt tájékoztatást. A beállítási minta konzolalkalmazásokban való használatáról további információt a .NET Beállítások mintája című témakörben talál.
Hierarchikus konfiguráció kötése
A kapcsolódó konfigurációs értékek olvasásának elsődleges módja a beállítási minta használata. Például a következő konfigurációs értékek olvasásához:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Hozza létre a következő PositionOptions osztályt:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}
Egy beállításosztály:
- Nem lehet absztrakt, és nyilvános, paraméter nélküli konstruktorral kell rendelkeznie.
- A típus összes nyilvános írási-olvasási tulajdonsága kötött.
- A mezők nincsenek megkötve. Az előző kódban a
Positionnincs kötés alatt. APositionmező célja, hogy ne kelljen a"Position"sztringet kézzel kódolni az alkalmazásban, amikor az osztályt egy konfigurációs szolgáltatóhoz kötjük.
A következő kód:
- A ConfigurationBinder.Bind meghívásával köti az osztályt
PositionOptionsaPositionszakaszhoz. - Megjeleníti a
Positionkonfigurációs adatokat.
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
ConfigurationBinder.Get<T> köti és visszaadja a megadott típust.
ConfigurationBinder.Get<T> lehet, hogy kényelmesebb, mint a használata ConfigurationBinder.Bind. Az alábbi kód bemutatja, hogyan használható ConfigurationBinder.Get<T> az PositionOptions osztály:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
A beállítási minta használatakor alternatív módszer a szakasz kötése Position és hozzáadása a függőséginjektálási szolgáltatás tárolóhoz. A következő kódban PositionOptions hozzáadásra kerül a szolgáltatástárolóhoz Configure-sel és konfigurációhoz kötve:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
Az előző kód használatával a következő kód felolvassa a pozícióbeállításokat:
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}");
}
}
Az előző kódban az alkalmazás elindítása után a JSON-konfigurációs fájl módosításai nem lesznek beolvasva. Az alkalmazás elindítása utáni módosítások olvasásához használja az IOptionsSnapshot parancsot.
Beállítási felületek
-
Nem támogatja a következőt:
- A konfigurációs adatok olvasása az alkalmazás elindítása után.
- Elnevezett beállítások
- Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Olyan helyzetekben hasznos, ahol a beállításokat minden kérésnél újra kell cserélni. További információ: Az IOptionsSnapshot használata a frissített adatok olvasásához.
- Hatókörként van regisztrálva, ezért nem adhatók be egy Singleton-szolgáltatásba.
- Támogatja a névvel ellátott beállításokat
- A beállítási lehetőségek lekérésére és a
TOptionspéldányok beállításainak kezelésére szolgál. - Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Supports:
- Értesítések módosítása
- elnevezett beállítások
- Újratölthető konfiguráció
- Szelektív beállítások érvénytelenítése (IOptionsMonitorCache<TOptions>)
A konfiguráció utáni forgatókönyvek lehetővé teszik a beállítások beállítását vagy módosítását az összes IConfigureOptions<TOptions> konfiguráció után.
IOptionsFactory<TOptions> új beállításpéldányok létrehozásáért felelős. Egyetlen Create metódussal rendelkezik. Az alapértelmezett implementáció összegyűjti az összes regisztrált IConfigureOptions<TOptions> és IPostConfigureOptions<TOptions>, először futtatja az összes konfigurációt, majd végrehajtja a konfiguráció utáni műveleteket. Megkülönbözteti IConfigureNamedOptions<TOptions> és IConfigureOptions<TOptions> között, és csak a megfelelő felületet hívja meg.
IOptionsMonitorCache<TOptions>-t a IOptionsMonitor<TOptions> használja a TOptions példányok gyorsítótárazására. Az IOptionsMonitorCache<TOptions> érvényteleníti a figyelőben lévő beállításpéldányokat, hogy az értéket újraszámítsák TryRemove. Az értékek manuálisan is bevezethetők a TryAdd. A Clear metódus akkor használatos, ha az összes elnevezett példányt igény szerint újra létre kell hozni.
Frissített adatok olvasása az IOptionsSnapshot használatával
IOptionsSnapshot<TOptions> használata:
- A rendszer kérésenként egyszer számítja ki a beállításokat, amikor a kérés teljes élettartama alatt hozzáférnek és gyorsítótáraznak.
- Jelentős teljesítménycsökkenést okozhat, mivel egy rétegezett szolgáltatás , amely kérésenként újraszámításra kerül. További információkért tekintse meg ezt a GitHub-problémát , és javítsa a konfigurációs kötés teljesítményét.
- A konfiguráció módosításai az alkalmazás elindítása után jelennek meg, amikor olyan konfigurációszolgáltatókat használ, amelyek támogatják a frissített konfigurációs értékek olvasását.
A különbség a következők között IOptionsMonitorIOptionsSnapshot van:
-
IOptionsMonitorEgy Singleton-szolgáltatás , amely bármikor lekéri az aktuális beállításértékeket, ami különösen hasznos az egyszeri függőségekben. -
IOptionsSnapshotegy hatókörű szolgáltatás, és azIOptionsSnapshot<T>objektum létrehozásának időpontjában pillanatképet nyújt a lehetőségekről. A beállítási pillanatképek átmeneti és hatókörű függőségekhez használhatók.
Az alábbi kód a következőt használja 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}");
}
}
Az alábbi kód regisztrál egy konfigurációs példányt, amely a következőhöz kötődik: MyOptions.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Az előző kódban a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után beolvasásra kerülnek.
IOptionsMonitor
Az alábbi kód regisztrál egy konfigurációs példányt, amelyhez MyOptions kapcsolódik.
using SampleApp.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<MyOptions>(
builder.Configuration.GetSection("MyOptions"));
var app = builder.Build();
Az alábbi példa IOptionsMonitor<TOptions>használ:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
Az elnevezett beállítások támogatása az IConfigureNamedOptions használatával
Elnevezett beállítások:
- Akkor hasznos, ha több konfigurációs szakasz is ugyanahhoz a tulajdonsághoz kapcsolódik.
- Megkülönbözteti a kis- és nagybetűket.
Fontolja meg a következő appsettings.json fájlt:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
Ahelyett, hogy a TopItem:Month és TopItem:Year összekapcsolásához két osztályt hozna létre, az alábbi osztály használatos az egyes szakaszokhoz:
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 következő kód konfigurálja a névvel ellátott beállításokat:
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();
Az alábbi kód a névvel ellátott beállításokat jeleníti meg:
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" );
}
}
Minden opció egy nevesített példány.
IConfigureOptions<TOptions> példányokat úgy kezelik, mint amelyek a Options.DefaultName példányt célozzák meg, ami string.Empty.
IConfigureNamedOptions<TOptions> is megvalósítja IConfigureOptions<TOptions>. Az alapértelmezett implementáció logikát tartalmaz, hogy az egyes elemeket megfelelően használja. A null névvel ellátott beállítás az összes elnevezett példányt megcélozza egy adott elnevezett példány helyett.
ConfigureAll és PostConfigureAll használja ezt az egyezményt.
OptionsBuilder API
OptionsBuilder<TOptions> példányok konfigurálására van használva TOptions.
OptionsBuilder Egyszerűbbé teszi az elnevezett beállítások létrehozását, mivel ez csak egy paraméter a kezdeti AddOptions<TOptions>(string optionsName) híváshoz, ahelyett, hogy az összes későbbi hívásban megjelenne. A beállítások érvényesítése és a ConfigureOptions szolgáltatásfüggőségeket elfogadó túlterhelések csak a OptionsBuilder elérhetők.
OptionsBuildera Beállítások érvényesítési szakaszában használható.
Lásd: Az AddOptions használata az egyéni tárház konfigurálásához az egyéni tárház hozzáadásával kapcsolatos információkért.
Beállítások konfigurálása a DI-szolgáltatások használatával
A szolgáltatások a függőséginjektálásból érhetők el, a beállítások kétféleképpen konfigurálhatók:
Adjon át egy konfigurációs delegátumot a ConfigureOptionsBuilder<TOptions> parancsnak.
OptionsBuilder<TOptions>olyan túlterheléseket Configure biztosít, amelyek legfeljebb öt szolgáltatás használatát teszik lehetővé a beállítások konfigurálásához: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));Hozzon létre egy típust, amely megvalósítja IConfigureOptions<TOptions> vagy IConfigureNamedOptions<TOptions>, és regisztrálja a típust szolgáltatásként.
Javasoljuk, hogy adjon át egy konfigurációs delegáltat Configure-nek, mivel a szolgáltatás létrehozása összetettebb. A típus létrehozása egyenértékű azzal, amit a keretrendszer a híváskor Configurevégez. A hívás Configure egy átmeneti általánost IConfigureNamedOptions<TOptions>regisztrál, amelynek konstruktora elfogadja a megadott általános szolgáltatástípusokat.
Beállítások érvényesítése
A beállítások érvényesítése lehetővé teszi a beállításértékek érvényesítését.
Fontolja meg a következő appsettings.json fájlt:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
A következő osztály a konfigurációs szakaszhoz való kötésre "MyConfig" szolgál, és néhány DataAnnotations szabályt alkalmaz:
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 következő kód:
- Hívásokat AddOptions az OptionsBuilder<TOptions> megszerzéséhez, amely az
MyConfigOptionsosztályhoz kötődik. - Az érvényesítés engedélyezésére hívja meg a ValidateDataAnnotations a
DataAnnotationshasználatával.
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();
A ValidateDataAnnotations bővítménymetódus a Microsoft.Extensions.Options.DataAnnotations NuGet-csomagban van definiálva. Az SDK-t használó Microsoft.NET.Sdk.Web webalkalmazások esetében a csomagra implicit módon hivatkozik a megosztott keretrendszer.
Az alábbi kód a konfigurációs értékeket vagy az érvényesítési hibákat jeleníti meg:
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 következő kód egy összetettebb érvényesítési szabályt alkalmaz meghatalmazott használatával:
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> és IValidatableObject
A következő osztály implementálja 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 lehetővé teszi az érvényesítési kód Program.cs-ből való áthelyezését egy osztályba.
Az előző kód használatával az Program.cs ellenőrzés a következő kóddal van engedélyezve.
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();
A beállítások érvényesítése a következőt is támogatja IValidatableObject: Egy osztály osztályszintű ellenőrzésének végrehajtása magában az osztályban:
- Implementálja az interfészt
IValidatableObjectés annak metódusát Validate az osztályon belül. -
ValidateDataAnnotations hívása
Program.cs.
ValidateOnStart
A beállítások érvényesítése az első alkalommal fut, amikor létrejön egy IOptions<TOptions>, IOptionsSnapshot<TOptions>vagy IOptionsMonitor<TOptions> implementáció. A beállítások azonnali ellenőrzéséhez, amikor az alkalmazás elindul, hívja meg a ValidateOnStart a Program.cs-ben:
builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.ValidateOnStart();
Beállítások a konfigurációt követően
Utókonfiguráció beállítása a következővel IPostConfigureOptions<TOptions>. A konfiguráció utáni futtatás az összes IConfigureOptions<TOptions> konfiguráció után megtörténik:
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 a névvel ellátott beállítások utólagos konfigurálásához érhető el:
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();
A PostConfigureAll eszközt az összes konfigurációs példány utólagos konfigurálására használja:
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";
});
Hozzáférési beállítások a következőben: Program.cs
Az IOptions<TOptions> vagy IOptionsMonitor<TOptions> eléréséhez a Program.cs nevű helyen, hívja a GetRequiredService számot a következőhöz WebApplication.Services:
var app = builder.Build();
var option1 = app.Services.GetRequiredService<IOptionsMonitor<MyOptions>>()
.CurrentValue.Option1;
További erőforrások
Az opciós minta osztályok használatával erősen típusos hozzáférést biztosít a kapcsolódó beállítások csoportjaihoz. Ha a konfigurációs beállításokat forgatókönyvek szerint külön osztályokba különítjük el, az alkalmazás két fontos szoftvermérnöki alapelvnek felel meg:
-
Encapsulation:
- A konfigurációs beállításoktól függő osztályok csak az általuk használt konfigurációs beállításoktól függnek.
-
Az aggodalmak elkülönítése:
- Az alkalmazás különböző részeinek beállításai nem függenek egymástól, és nincsenek összekapcsolva.
A beállítások emellett a konfigurációs adatok ellenőrzésére szolgáló mechanizmust is biztosítanak. További információt a Beállítások érvényesítési szakaszában talál.
Ez a témakör a ASP.NET Core beállítási mintájáról nyújt tájékoztatást. A beállítási minta konzolalkalmazásokban való használatáról további információt a .NET Beállítások mintája című témakörben talál.
Mintakód megtekintése vagy letöltése (letöltés)
Hierarchikus konfiguráció kötése
A kapcsolódó konfigurációs értékek olvasásának elsődleges módja a beállítási minta használata. Például a következő konfigurációs értékek olvasásához:
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
Hozza létre a következő PositionOptions osztályt:
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; }
public string Name { get; set; }
}
Egy beállításosztály:
- Nem lehet absztrakt, és nyilvános, paraméter nélküli konstruktorral kell rendelkeznie.
- A típus összes nyilvános írási-olvasási tulajdonsága kötött.
- A mezők nincsenek megkötve. Az előző kódban a
Positionnincs kötés alatt. APositiontulajdonságot a rendszer úgy használja, hogy a sztringet"Position"ne kelljen keményen kódolni az alkalmazásban, amikor az osztályt egy konfigurációszolgáltatóhoz köti.
A következő kód:
- A ConfigurationBinder.Bind meghívásával köti az osztályt
PositionOptionsaPositionszakaszhoz. - Megjeleníti a
Positionkonfigurációs adatokat.
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
ConfigurationBinder.Get<T> köti és visszaadja a megadott típust.
ConfigurationBinder.Get<T> lehet, hogy kényelmesebb, mint a használata ConfigurationBinder.Bind. Az alábbi kód bemutatja, hogyan használható ConfigurationBinder.Get<T> az PositionOptions osztály:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
A beállítási minta használatakor alternatív módszer a szakasz kötése Position és hozzáadása a függőséginjektálási szolgáltatás tárolóhoz. A következő kódban PositionOptions hozzáadásra kerül a szolgáltatástárolóhoz Configure-sel és konfigurációhoz kötve:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<PositionOptions>(Configuration.GetSection(
PositionOptions.Position));
services.AddRazorPages();
}
Az előző kód használatával a következő kód felolvassa a pozícióbeállításokat:
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}");
}
}
Az előző kódban az alkalmazás elindítása után a JSON-konfigurációs fájl módosításai nem lesznek beolvasva. Az alkalmazás elindítása utáni módosítások olvasásához használja az IOptionsSnapshot parancsot.
Beállítási felületek
-
Nem támogatja a következőt:
- A konfigurációs adatok olvasása az alkalmazás elindítása után.
- Elnevezett beállítások
- Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Olyan helyzetekben hasznos, ahol a beállításokat minden kérésnél újra kell cserélni. További információ: Az IOptionsSnapshot használata a frissített adatok olvasásához.
- Egy Scoped ként van regisztrálva; ezért nem lehet egyetlen Singleton-szolgáltatásba injektálni.
- Támogatja a névvel ellátott beállításokat
- A beállítási lehetőségek lekérésére és a
TOptionspéldányok beállításainak kezelésére szolgál. - Singleton-ként van regisztrálva, és beilleszthető bármilyen szolgáltatási élettartamba.
- Supports:
- Értesítések módosítása
- Elnevezett beállítások
- Újratölthető konfiguráció
- Szelektív beállítások érvénytelenítése (IOptionsMonitorCache<TOptions>)
A konfiguráció utáni forgatókönyvek lehetővé teszik a beállítások beállítását vagy módosítását az összes IConfigureOptions<TOptions> konfiguráció után.
IOptionsFactory<TOptions> új beállításpéldányok létrehozásáért felelős. Egyetlen Create metódussal rendelkezik. Az alapértelmezett implementáció összegyűjti az összes regisztrált IConfigureOptions<TOptions> és IPostConfigureOptions<TOptions>, először futtatja az összes konfigurációt, majd végrehajtja a konfiguráció utáni műveleteket. Megkülönbözteti IConfigureNamedOptions<TOptions> és IConfigureOptions<TOptions> között, és csak a megfelelő felületet hívja meg.
IOptionsMonitorCache<TOptions>-t a IOptionsMonitor<TOptions> használja a TOptions példányok gyorsítótárazására. Az IOptionsMonitorCache<TOptions> érvényteleníti a figyelőben lévő beállításpéldányokat, hogy az értéket újraszámítsák TryRemove. Az értékek manuálisan is bevezethetők a TryAdd. A Clear metódus akkor használatos, ha az összes elnevezett példányt igény szerint újra létre kell hozni.
Frissített adatok olvasása az IOptionsSnapshot használatával
A IOptionsSnapshot<TOptions> beállításokat kérésenként egyszer számítja ki a rendszer, és gyorsítótárazza a kérés teljes élettartama alatt. A konfiguráció módosításai az alkalmazás elindítása után jelennek meg, amikor olyan konfigurációszolgáltatókat használ, amelyek támogatják a frissített konfigurációs értékek olvasását.
A különbség a következők között IOptionsMonitorIOptionsSnapshot van:
-
IOptionsMonitorEgy Singleton-szolgáltatás , amely bármikor lekéri az aktuális beállításértékeket, ami különösen hasznos az egyszeri függőségekben. -
IOptionsSnapshotegy hatókörű szolgáltatás, és azIOptionsSnapshot<T>objektum létrehozásának időpontjában pillanatképet nyújt a lehetőségekről. A beállítási pillanatképek átmeneti és hatókörű függőségekhez használhatók.
Az alábbi kód a következőt használja 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}");
}
}
Az alábbi kód regisztrál egy konfigurációs példányt, amely a következőhöz kötődik: MyOptions.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Az előző kódban a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után beolvasásra kerülnek.
IOptionsMonitor
Az alábbi kód regisztrál egy konfigurációs példányt, amelyhez MyOptions kapcsolódik.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
Az alábbi példa IOptionsMonitor<TOptions>használ:
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}");
}
}
Az előző kódban alapértelmezés szerint a JSON-konfigurációs fájl módosításai az alkalmazás elindítása után jelennek meg.
Az elnevezett beállítások támogatása az IConfigureNamedOptions használatával
Elnevezett beállítások:
- Akkor hasznos, ha több konfigurációs szakasz is ugyanahhoz a tulajdonsághoz kapcsolódik.
- Megkülönbözteti a kis- és nagybetűket.
Fontolja meg a következő appsettings.json fájlt:
{
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
}
Ahelyett, hogy a TopItem:Month és TopItem:Year összekapcsolásához két osztályt hozna létre, az alábbi osztály használatos az egyes szakaszokhoz:
public class TopItemSettings
{
public const string Month = "Month";
public const string Year = "Year";
public string Name { get; set; }
public string Model { get; set; }
}
A következő kód konfigurálja a névvel ellátott beállításokat:
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();
}
Az alábbi kód a névvel ellátott beállításokat jeleníti meg:
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" );
}
}
Minden opció egy nevesített példány.
IConfigureOptions<TOptions> példányokat úgy kezelik, mint amelyek a Options.DefaultName példányt célozzák meg, ami string.Empty.
IConfigureNamedOptions<TOptions> is megvalósítja IConfigureOptions<TOptions>. Az alapértelmezett implementáció logikát tartalmaz, hogy az egyes elemeket megfelelően használja. A null névvel ellátott beállítás az összes elnevezett példányt megcélozza egy adott elnevezett példány helyett.
ConfigureAll és PostConfigureAll használja ezt az egyezményt.
OptionsBuilder API
OptionsBuilder<TOptions> példányok konfigurálására van használva TOptions.
OptionsBuilder Egyszerűbbé teszi az elnevezett beállítások létrehozását, mivel ez csak egy paraméter a kezdeti AddOptions<TOptions>(string optionsName) híváshoz, ahelyett, hogy az összes későbbi hívásban megjelenne. A beállítások érvényesítése és a ConfigureOptions szolgáltatásfüggőségeket elfogadó túlterhelések csak a OptionsBuilder elérhetők.
OptionsBuildera Beállítások érvényesítési szakaszában használható.
Lásd: Az AddOptions használata az egyéni tárház konfigurálásához az egyéni tárház hozzáadásával kapcsolatos információkért.
Beállítások konfigurálása a DI-szolgáltatások használatával
A szolgáltatások a függőséginjektálásból érhetők el, a beállítások kétféleképpen konfigurálhatók:
Adjon át egy konfigurációs delegátumot a ConfigureOptionsBuilder<TOptions> parancsnak.
OptionsBuilder<TOptions>olyan túlterheléseket Configure biztosít, amelyek legfeljebb öt szolgáltatás használatát teszik lehetővé a beállítások konfigurálásához:services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));Hozzon létre egy típust, amely megvalósítja IConfigureOptions<TOptions> vagy IConfigureNamedOptions<TOptions>, és regisztrálja a típust szolgáltatásként.
Javasoljuk, hogy adjon át egy konfigurációs delegáltat Configure-nek, mivel a szolgáltatás létrehozása összetettebb. A típus létrehozása egyenértékű azzal, amit a keretrendszer a híváskor Configurevégez. A hívás Configure egy átmeneti általánost IConfigureNamedOptions<TOptions>regisztrál, amelynek konstruktora elfogadja a megadott általános szolgáltatástípusokat.
Beállítások érvényesítése
A beállítások érvényesítése lehetővé teszi a beállításértékek érvényesítését.
Fontolja meg a következő appsettings.json fájlt:
{
"MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
}
A következő osztály a "MyConfig" konfigurációs szakaszhoz kötődik, és néhány DataAnnotations szabályt alkalmaz:
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 következő kód:
- Hívásokat AddOptions az OptionsBuilder<TOptions> megszerzéséhez, amely az
MyConfigOptionsosztályhoz kötődik. - Az érvényesítés engedélyezésére hívja meg a ValidateDataAnnotations a
DataAnnotationshasználatával.
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();
}
A ValidateDataAnnotations bővítménymetódus a Microsoft.Extensions.Options.DataAnnotations NuGet-csomagban van definiálva. Az SDK-t használó Microsoft.NET.Sdk.Web webalkalmazások esetében a csomagra implicit módon hivatkozik a megosztott keretrendszer.
Az alábbi kód a konfigurációs értékeket vagy az érvényesítési hibákat jeleníti meg:
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 következő kód egy összetettebb érvényesítési szabályt alkalmaz meghatalmazott használatával:
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();
}
IValidateOptions összetett ellenőrzéshez
A következő osztály implementálja 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 lehetővé teszi az érvényesítési kód StartUp-ből való áthelyezését egy osztályba.
Az előző kód használatával az Startup.ConfigureServices ellenőrzés a következő kóddal van engedélyezve.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfigOptions>(Configuration.GetSection(
MyConfigOptions.MyConfig));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions
<MyConfigOptions>, MyConfigValidation>());
services.AddControllersWithViews();
}
Beállítások a konfigurációt követően
Utókonfiguráció beállítása a következővel IPostConfigureOptions<TOptions>. A konfiguráció utáni futtatás az összes IConfigureOptions<TOptions> konfiguráció után megtörténik:
services.PostConfigure<MyOptions>(myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
PostConfigure a névvel ellátott beállítások utólagos konfigurálásához érhető el:
services.PostConfigure<MyOptions>("named_options_1", myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
A PostConfigureAll eszközt az összes konfigurációs példány utólagos konfigurálására használja:
services.PostConfigureAll<MyOptions>(myOptions =>
{
myOptions.Option1 = "post_configured_option1_value";
});
Hozzáférés a beállításokhoz az indítás során
IOptions<TOptions> és IOptionsMonitor<TOptions> használható, Startup.Configuremivel a szolgáltatások a Configure metódus végrehajtása előtt jönnek létre.
public void Configure(IApplicationBuilder app,
IOptionsMonitor<MyOptions> optionsAccessor)
{
var option1 = optionsAccessor.CurrentValue.Option1;
}
Ne használja a IOptions<TOptions> vagy IOptionsMonitor<TOptions> a Startup.ConfigureServices. A szolgáltatásregisztrációk megrendelése miatt inkonzisztens beállításállapot létezhet.
Options.ConfigurationExtensions NuGet-csomag
A Microsoft.Extensions.Options.ConfigurationExtensions csomag implicit módon hivatkozik ASP.NET Core-alkalmazásokban.