Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Díky injektáži závislostí může registrace služeb a jejich odpovídající konfigurace využít vzor možností. Vzor možností umožňuje uživatelům vaší knihovny (a vašim službám) vyžadovat instance rozhraní možností, kde TOptions je třída možností. Využívání možností konfigurace prostřednictvím objektů silného typu pomáhá zajistit konzistentní reprezentaci hodnot, umožňuje ověřování pomocí datových poznámek a odstraňuje zátěž ruční analýzy řetězcových hodnot. Existuje mnoho poskytovatelů konfigurace pro uživatele vaší knihovny. S těmito poskytovateli můžou uživatelé konfigurovat vaši knihovnu mnoha způsoby.
Jako autor knihovny .NET se dozvíte obecné pokyny, jak správně vystavit vzor možností uživatelům knihovny. Existují různé způsoby, jak dosáhnout stejné věci, a několik aspektů, které je potřeba vzít v úvahu.
Názvoslovné konvence
Podle konvence jsou metody rozšíření zodpovědné za registraci služeb pojmenovány Add{Service}, kde {Service} je smysluplný a popisný název.
Add{Service} Metody rozšíření jsou v ASP.NET Core a .NET běžné.
✔️ Zvažte názvy, které odliší vaši službu od jiných nabídek.
❌ NEPOUŽÍVEJTE názvy, které jsou již součástí ekosystému .NET z oficiálních balíčků Microsoftu.
✔️ ZVAŽTE pojmenování statických tříd, které zpřístupňují rozšiřující metody jako {Type}Extensions, kde {Type} je typ, který rozšiřujete.
Pokyny k názvovému prostoru
Balíčky Microsoftu využívají Microsoft.Extensions.DependencyInjection obor názvů ke sjednocení registrace různých nabídek služeb.
✔️ ZVAŽTE obor názvů, který jasně identifikuje vaši nabídku balíčků.
❌ NEPOUŽÍVEJTE Microsoft.Extensions.DependencyInjection obor názvů pro jiné než oficiální balíčky Společnosti Microsoft.
Bez parametrů
Pokud vaše služba může pracovat s minimální nebo žádnou explicitní konfigurací, zvažte metodu rozšíření bez parametrů.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services)
{
services.AddOptions<LibraryOptions>()
.Configure(options =>
{
// Specify default option values
});
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
- Volání OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection) s parametrem typu
LibraryOptions - Spojuje volání s řetězcem Configure, které určuje výchozí hodnoty nastavení.
IConfiguration parametr
Když vytvoříte knihovnu, která uživatelům zpřístupňuje mnoho možností, můžete zvážit vyžadování metody rozšíření parametru IConfiguration . Očekávaná IConfiguration instance by měla být vymezena na pojmenovanou část konfigurace pomocí IConfiguration.GetSection funkce.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
IConfiguration namedConfigurationSection)
{
// Default library options are overridden
// by bound configuration values.
services.Configure<LibraryOptions>(namedConfigurationSection);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Návod
Metoda Configure<TOptions>(IServiceCollection, IConfiguration) je součástí Microsoft.Extensions.Options.ConfigurationExtensions balíčku NuGet.
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
-
IConfiguration Definuje parametr.
namedConfigurationSection - Volání Configure<TOptions>(IServiceCollection, IConfiguration), které předává parametr obecného typu
LibraryOptionsa instancinamedConfigurationSectionpro konfiguraci.
Spotřebitelé v tomto vzoru poskytují omezenou IConfiguration instanci pojmenované části:
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(
builder.Configuration.GetSection("LibraryOptions"));
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Volání .AddMyLibraryService se provede u IServiceCollection typu.
Záleží na vás jako autorovi knihovny, zda zadáte výchozí hodnoty.
Poznámka:
Konfiguraci je možné svázat s instancí možností. Existuje však riziko kolizí názvů , což způsobí chyby. Navíc když tímto způsobem ručně vytvoříte vazbu, omezíte spotřebu vzorů možností na čtení jednou. Změny nastavení nebudou znovu vázány, protože uživatelé nebudou moci používat rozhraní IOptionsMonitor .
services.AddOptions<LibraryOptions>()
.Configure<IConfiguration>(
(options, configuration) =>
configuration.GetSection("LibraryOptions").Bind(options));
Místo toho byste měli použít rozšiřující metodu BindConfiguration. Tato metoda rozšíření sváže konfiguraci s instancí možností a také zaregistruje zdroj tokenu změn pro oddíl konfigurace. To umožňuje uživatelům používat rozhraní IOptionsMonitor .
Konfigurační oddíl s parametrem cesty
Příjemci vaší knihovny mohou chtít zadat cestu ke konfiguračnímu oddílu pro vytvoření vazby souvisejícího TOptions typu. V tomto scénáři definujete string parametr v metodě rozšíření.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
string configSectionPath)
{
services.AddOptions<SupportOptions>()
.BindConfiguration(configSectionPath)
.ValidateDataAnnotations()
.ValidateOnStart();
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
- Definuje
stringparametr.configSectionPath - Volá:
-
AddOptions parametrem obecného typu
SupportOptions -
BindConfiguration s daným
configSectionPathparametrem - ValidateDataAnnotations umožnit validaci datových anotací
- ValidateOnStart vynutit ověřování při startu namísto během běhu programu
-
AddOptions parametrem obecného typu
V dalším příkladu se k povolení ověření datových poznámek použije balíček NuGet Microsoft.Extensions.Options.DataAnnotations . Třída SupportOptions je definována takto:
using System.ComponentModel.DataAnnotations;
public sealed class SupportOptions
{
[Url]
public string? Url { get; set; }
[Required, EmailAddress]
public required string Email { get; set; }
[Required, DataType(DataType.PhoneNumber)]
public required string PhoneNumber { get; set; }
}
Představte si, že se používá následující soubor JSON appsettings.json :
{
"Support": {
"Url": "https://support.example.com",
"Email": "help@support.example.com",
"PhoneNumber": "+1(888)-SUPPORT"
}
}
Action<TOptions> parametr
Spotřebitelé vaší knihovny mohou mít zájem o poskytnutí výrazu lambda, který poskytuje instanci vaší třídy možností. V tomto scénáři definujete Action<LibraryOptions> parametr v metodě rozšíření.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
Action<LibraryOptions> configureOptions)
{
services.Configure(configureOptions);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
-
Action<T> Definuje parametr
configureOptions, kdeTjeLibraryOptions - Volání Configure s danou
configureOptionsakcí
Příjemci v tomto vzoru poskytují výraz lambda (nebo delegát, který tento Action<LibraryOptions> parametr splňuje):
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(options =>
{
// User defined option values
// options.SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Parametr instance možnosti
Uživatelé vaší knihovny mohou raději poskytnout přímo vloženou instanci parametrů. V tomto scénáři zveřejníte rozšiřující metodu, která přebírá instanci objektu options , LibraryOptions.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
LibraryOptions userOptions)
{
services.AddOptions<LibraryOptions>()
.Configure(options =>
{
// Overwrite default option values
// with the user provided options.
// options.SomeValue = userOptions.SomeValue;
});
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
- Volání OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection) s parametrem typu
LibraryOptions - Zřetězí volání na Configure, které stanovuje výchozí hodnoty možností, jež mohou být přepsány z této konkrétní
userOptionsinstance.
Uživatelé v tomto vzoru poskytují instanci třídy LibraryOptions, definující požadované hodnoty vlastností přímo:
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(new LibraryOptions
{
// Specify option values
// SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Po konfiguraci
Po vázání nebo zadání všech hodnot možností konfigurace je k dispozici funkce po konfiguraci. Když odkryjete stejný Action<TOptions> parametr, který je podrobně popsán dříve, můžete se rozhodnout použít PostConfigure. Po dokončení konfigurace se spustí po všech .Configure voláních. Existuje několik důvodů, proč byste měli zvážit použití PostConfigure:
-
Pořadí provádění: Můžete přepsat všechny hodnoty konfigurace, které byly nastaveny ve
.Configurevoláních. - Ověření: Po použití všech ostatních konfigurací můžete ověřit, jestli jsou nastavené výchozí hodnoty.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
Action<LibraryOptions> configureOptions)
{
services.PostConfigure(configureOptions);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
V předchozím kódu je AddMyLibraryService
- Rozšíří instanci IServiceCollection
-
Action<T> Definuje parametr
configureOptions, kdeTjeLibraryOptions - Volání PostConfigure s danou
configureOptionsakcí
Spotřebitelé v tomto vzoru poskytují výraz lambda (nebo delegát, který splňuje tento parametr Action<LibraryOptions>), stejně jako u parametru Action<TOptions> ve scénáři konfigurace, která není post konfigurací.
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(options =>
{
// Specify option values
// options.SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Viz také
- Model možností v .NET
- Injektáž závislostí v .NET
- pokyny pro injekci závislostí