Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Met behulp van afhankelijkheidsinjectie kan het registreren van uw services en de bijbehorende configuraties gebruikmaken van het optiespatroon. Met het optiespatroon kunnen gebruikers van uw bibliotheek (en uw services) exemplaren van optiesinterfaces vereisen, waarbij TOptions uw optiesklasse is. Het gebruik van configuratieopties via sterk getypte objecten helpt bij het garanderen van consistente waardeweergave, maakt validatie mogelijk met gegevensannotaties en verwijdert de last van het handmatig parseren van tekenreekswaarden. Er zijn veel configuratieproviders die gebruikers van uw bibliotheek kunnen gebruiken. Met deze providers kunnen consumenten uw bibliotheek op veel manieren configureren.
Als auteur van een .NET-bibliotheek leert u algemene richtlijnen voor het correct beschikbaar maken van het optiespatroon voor consumenten van uw bibliotheek. Er zijn verschillende manieren om hetzelfde te bereiken, en verschillende overwegingen die u moet maken.
Naamgevingsconventies
Conventioneel worden extensiemethoden die verantwoordelijk zijn voor het registreren van services benoemd Add{Service}, waar {Service} een betekenisvolle en beschrijvende naam is.
Add{Service} extensiemethoden zijn gebruikelijk in ASP.NET Core en .NET.
✔️ HOUD REKENING met namen die uw service onderscheiden van andere aanbiedingen.
❌ GEBRUIK GEEN namen die al deel uitmaken van het .NET-ecosysteem van officiële Microsoft-pakketten.
✔️ OVERWEEG statische klassen te benoemen die extensiemethoden beschikbaar maken als {Type}Extensions, waar {Type} is het type dat u uitbreidt.
Richtlijnen voor namespaces
Microsoft-pakketten maken gebruik van de Microsoft.Extensions.DependencyInjection naamruimte om de registratie van verschillende serviceaanbiedingen te samenvoegen.
✔️ OVERWEEG een naamruimte die uw pakketaanbod duidelijk identificeert.
❌ GEBRUIK DE Microsoft.Extensions.DependencyInjection naamruimte NIET voor niet-officiële Microsoft-pakketten.
Parameterloos
Als uw service kan werken met minimale of geen expliciete configuratie, kunt u een parameterloze extensiemethode overwegen.
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;
}
}
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Roept OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection) aan met de typeparameter van
LibraryOptions - Koppelt een aanroep naar Configure, waarmee de standaardoptiewaarden worden opgegeven
IConfiguration-parameter
Wanneer u een bibliotheek maakt die veel opties beschikbaar maakt voor consumenten, kunt u overwegen om een IConfiguration parameterextensiemethode te vereisen. Het verwachte IConfiguration exemplaar moet worden afgestemd op een benoemde sectie van de configuratie met behulp van de IConfiguration.GetSection functie.
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;
}
}
Aanbeveling
De Configure<TOptions>(IServiceCollection, IConfiguration) methode maakt deel uit van het Microsoft.Extensions.Options.ConfigurationExtensions NuGet-pakket.
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Definieert een IConfiguration parameter
namedConfigurationSection - Roep Configure<TOptions>(IServiceCollection, IConfiguration) aan, geef de generieke typeparameter van
LibraryOptionsdoor, en configureer hetnamedConfigurationSectionexemplaar
Consumenten via dit patroon gebruiken de gescope IConfiguration exemplaar van de benoemde sectie.
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();
De aanroep van .AddMyLibraryService wordt gedaan op het IServiceCollection type.
Als auteur van de bibliotheek kunt u standaardwaarden opgeven.
Opmerking
Het is mogelijk om de configuratie te binden aan een exemplaar van opties. Er is echter een risico op naamconflicten, wat fouten veroorzaakt. Als u op deze manier handmatig bindingen gebruikt, beperkt u bovendien het verbruik van uw optiespatroon tot een keer lezen. Wijzigingen in instellingen worden niet opnieuw gebonden, omdat consumenten de IOptionsMonitor-interface niet kunnen gebruiken.
services.AddOptions<LibraryOptions>()
.Configure<IConfiguration>(
(options, configuration) =>
configuration.GetSection("LibraryOptions").Bind(options));
In plaats daarvan moet u de BindConfiguration extensiemethode gebruiken. Deze extensiemethode verbindt de configuratie met het exemplaar van opties en registreert ook een wijzigingstokenbron voor de configuratiesectie. Hierdoor kunnen consumenten de IOptionsMonitor-interface gebruiken.
Configuratiesectiepadparameter
Consumenten van uw bibliotheek willen mogelijk het pad naar de configuratiesectie opgeven om uw onderliggende TOptions type te binden. In dit scenario definieert u een string parameter in uw extensiemethode.
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;
}
}
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Definieert een
stringparameterconfigSectionPath - Oproepen:
-
AddOptions met de algemene typeparameter van
SupportOptions -
BindConfiguration met de opgegeven
configSectionPathparameter - ValidateDataAnnotations gegevensannotatievalidatie inschakelen
- ValidateOnStart validatie afdwingen bij starten in plaats van in runtime
-
AddOptions met de algemene typeparameter van
In het volgende voorbeeld wordt het NuGet-pakket Microsoft.Extensions.Options.DataAnnotations gebruikt om validatie van gegevensaantekeningen in te schakelen. De SupportOptions klasse wordt als volgt gedefinieerd:
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; }
}
Stel dat het volgende JSON -appsettings.json-bestand wordt gebruikt:
{
"Support": {
"Url": "https://support.example.com",
"Email": "help@support.example.com",
"PhoneNumber": "+1(888)-SUPPORT"
}
}
Action<TOptions>-parameter
Consumenten van uw bibliotheek zijn mogelijk geïnteresseerd in het leveren van een lambda-expressie die een exemplaar van uw optiesklasse oplevert. In dit scenario definieert u een Action<LibraryOptions> parameter in uw extensiemethode.
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;
}
}
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Definieert een Action<T> parameter
configureOptionswaarTisLibraryOptions - Aanroepen die de Configure actie hebben gekregen
configureOptions
Gebruikers in dit patroon bieden een lambda-uitdrukking (of een delegate die voldoet aan de eisen van de Action<LibraryOptions> parameter):
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();
Parameter voor optie-instantie
Gebruikers van uw bibliotheek geven mogelijk de voorkeur aan het leveren van een inline-optie-exemplaar. In dit scenario maakt u een extensiemethode beschikbaar die een exemplaar van uw optieobject gebruikt. 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;
}
}
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Roept OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection) aan met de typeparameter van
LibraryOptions - Koppelt een oproep naar Configure, waarmee standaardoptiewaarden worden gespecificeerd die kunnen worden overschreven vanuit de gegeven
userOptionsexemplaar
Consumenten in dit patroon bieden een exemplaar van de LibraryOptions klasse, waarbij de gewenste eigenschapswaarden inline worden gedefinieerd:
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();
Postconfiguratie
Nadat alle waarden voor configuratieopties zijn gebonden of opgegeven, is de functionaliteit na de configuratie beschikbaar. Als u dezelfde Action<TOptions> parameter weergeeft die eerder is beschreven, kunt u ervoor kiezen om aan te roepen PostConfigure. Na het configureren worden alle .Configure aanroepen uitgevoerd. Er zijn enkele redenen waarom u zou willen overwegen PostConfigure te gebruiken.
-
Uitvoeringsvolgorde: U kunt alle configuratiewaarden die zijn ingesteld in de
.Configureaanroepen overschrijven. - Validatie: U kunt controleren of de standaardwaarden zijn ingesteld nadat alle andere configuraties zijn toegepast.
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;
}
}
In de voorgaande code is de AddMyLibraryService:
- Breidt een instantie van IServiceCollection uit
- Definieert een Action<T> parameter
configureOptionswaarTisLibraryOptions - Aanroepen die de PostConfigure actie hebben gekregen
configureOptions
Consumenten in dit patroon bieden een lambda-expressie (of een delegate die voldoet aan de Action<LibraryOptions> parameter), net zoals ze dat zouden doen bij de Action<TOptions> parameter in een configuratiescenario zonder post:
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();