.NET-functiebeheer
De .NET-bibliotheek voor functiebeheer biedt een manier om toepassingsfunctionaliteit te ontwikkelen en beschikbaar te maken op basis van functievlagmen. Zodra een nieuwe functie is ontwikkeld, hebben veel toepassingen speciale vereisten, zoals wanneer de functie moet worden ingeschakeld en onder welke omstandigheden. Deze bibliotheek biedt een manier om deze relaties te definiëren en kan ook worden geïntegreerd in algemene .NET-codepatronen om deze functies beschikbaar te maken.
Functievlagmen bieden een manier voor .NET- en ASP.NET Core-toepassingen om functies dynamisch in of uit te schakelen. Ontwikkelaars kunnen functievlagmen gebruiken in eenvoudige gebruiksvoorbeelden, zoals voorwaardelijke instructies, voor meer geavanceerde scenario's, zoals het voorwaardelijk toevoegen van routes of MVC-filters. Functievlagmen zijn gebouwd op het .NET Core-configuratiesysteem. Elke .NET Core-configuratieprovider kan fungeren als de backbone voor functievlaggen.
Hier volgen enkele voordelen van het gebruik van de .NET-functiebeheerbibliotheek:
Een algemene conventie voor functiebeheer
Lage barrière-naar-ingang
- Gebouwd op
IConfiguration
- Ondersteunt het instellen van de JSON-bestandsfunctievlag
- Gebouwd op
Levensduurbeheer van functievlagken
- Configuratiewaarden kunnen in realtime veranderen; functievlagmen kunnen consistent zijn in de hele aanvraag
Eenvoudige tot complexe scenario's behandeld
- Functies in-/uitschakelen via een declaratief configuratiebestand
- De status van de functie dynamisch evalueren op basis van aanroep naar server
API-extensies voor ASP.NET Core- en MVC-framework
- Routering
- Filters
- Actiekenmerken
De .NET-functiebeheerbibliotheek is open source. Ga naar de GitHub-opslagplaats voor meer informatie.
Functievlagmen
Functievlagmen bestaan uit twee delen, een naam en een lijst met functiefilters die worden gebruikt om de functie in te schakelen.
Functiefilters
Functiefilters definiëren een scenario voor wanneer een functie moet worden ingeschakeld. Wanneer een functie wordt geëvalueerd of deze is ingeschakeld of uitgeschakeld, wordt de lijst met functiefilters doorkruist totdat een van de filters besluit dat de functie moet worden ingeschakeld. Op dit moment wordt de functie beschouwd als ingeschakeld en wordt doorkruising door de functiefilters gestopt. Als er geen functiefilter aangeeft dat de functie moet worden ingeschakeld, wordt deze als uitgeschakeld beschouwd.
Een microsoft Edge-browserfunctiefilter kan bijvoorbeeld worden ontworpen. Met dit functiefilter worden alle functies geactiveerd waaraan deze zijn gekoppeld zolang een HTTP-aanvraag afkomstig is van Microsoft Edge.
Configuratie van functievlag
Het .NET Core-configuratiesysteem wordt gebruikt om de status van functievlagmen te bepalen. De basis van dit systeem is IConfiguration
. Elke provider IConfiguration
voor kan worden gebruikt als de functiestatusprovider voor de functievlagbibliotheek. Dit systeem maakt scenario's mogelijk, variërend van appsettings.json tot Azure-app Configuratie en meer.
Declaratie van functievlag
De bibliotheek voor functiebeheer ondersteunt appsettings.json als bron van functievlagken, omdat het een provider is voor het systeem van IConfiguration
.NET Core. Hieronder ziet u een voorbeeld van de indeling die wordt gebruikt voor het instellen van functievlagmen in een json-bestand.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in a json file
"FeatureManagement": {
"FeatureT": {
"EnabledFor": [
{
"Name": "AlwaysOn"
}
]
},
"FeatureU": {
"EnabledFor": []
},
"FeatureV": {
"EnabledFor": [
{
"Name": "TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
}
}
De FeatureManagement
sectie van het json-document wordt door de conventie gebruikt om instellingen voor functievlagken te laden. In de bovenstaande sectie zien we drie verschillende functies. Functies definiëren hun functiefilters met behulp van de EnabledFor
eigenschap. In de functiefilters voor FeatureT
, zien AlwaysOn
we . Dit functiefilter is ingebouwd en indien opgegeven wordt altijd de functie ingeschakeld. Voor AlwaysOn
het functiefilter is geen configuratie vereist, dus deze heeft alleen de Name
eigenschap. FeatureU
heeft geen filters in de EnabledFor
eigenschap en wordt dus nooit ingeschakeld. Alle functionaliteit die afhankelijk is van deze functie die wordt ingeschakeld, is niet toegankelijk zolang de functiefilters leeg blijven. Zodra er echter een functiefilter wordt toegevoegd waarmee de functie kan werken. FeatureV
hiermee geeft u een functiefilter met de naam TimeWindow
. Dit is een voorbeeld van een configureerbaar functiefilter. In het voorbeeld zien we dat het filter een Parameters
eigenschap heeft. Dit wordt gebruikt om het filter te configureren. In dit geval worden de begin- en eindtijden voor de functie geconfigureerd om actief te zijn.
Het gedetailleerde schema van de FeatureManagement
sectie vindt u hier.
Geavanceerd: Het gebruik van dubbele punt ':' is verboden in functievlagnamen.
Declaratie aan/uit
In het volgende fragment ziet u een alternatieve manier om een functie te definiëren die kan worden gebruikt voor aan/uit-functies.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in config file
"FeatureManagement": {
"FeatureT": true, // On feature
"FeatureX": false // Off feature
}
}
RequirementType
De RequirementType
eigenschap van een functievlag wordt gebruikt om te bepalen of de filters moeten worden gebruikt Any
of All
logica bij het evalueren van de status van een functie. Als RequirementType
dit niet is opgegeven, is Any
de standaardwaarde .
Any
betekent dat slechts één filter waar moet worden geëvalueerd om de functie in te schakelen.All
betekent dat elk filter waar moet evalueren om de functie in te schakelen.
Een RequirementType
van All
wijzigingen in de doorkruising. Als er geen filters zijn, is de functie eerst uitgeschakeld. Vervolgens worden de functiefilters doorkruist totdat een van de filters besluit dat de functie moet worden uitgeschakeld. Als er geen filter aangeeft dat de functie moet worden uitgeschakeld, wordt deze als ingeschakeld beschouwd.
"FeatureW": {
"RequirementType": "All",
"EnabledFor": [
{
"Name": "TimeWindow",
"Parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
},
{
"Name": "Percentage",
"Parameters": {
"Value": "50"
}
}
]
}
In het bovenstaande voorbeeld geeft u een RequirementType
vanAll
, FeatureW
wat betekent dat alle filters waar moeten zijn om de functie in te schakelen. In dit geval is de functie ingeschakeld voor 50% van de gebruikers tijdens het opgegeven tijdvenster.
Microsoft Feature Management-schema
De bibliotheek voor functiebeheer ondersteunt ook het gebruik van de Microsoft Feature Management schema
functievlagmen om functievlagmen te declareren. Dit schema is taalneutraal in oorsprong en wordt ondersteund door alle Microsoft-functiebeheerbibliotheken.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
}
]
}
}
]
}
}
Notitie
Als de feature_management
sectie in de configuratie kan worden gevonden, wordt de FeatureManagement
sectie genegeerd.
De bibliotheek voor functiebeheer ondersteunt appsettings.json als bron van functievlagken, omdat het een provider is voor het systeem van IConfiguration
.NET Core. Functievlagmen worden gedeclareerd met behulp van de Microsoft Feature Management schema
. Dit schema is taalneutraal in oorsprong en wordt ondersteund door alle Microsoft-functiebeheerbibliotheken.
Hieronder ziet u een voorbeeld van het declareren van functievlagmen in een json-bestand.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in a json file
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": false
},
{
"id": "FeatureU",
"enabled": true,
"conditions": {}
},
{
"id": "FeatureV",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 July 2023 00:00:00 GMT"
}
}
]
}
}
]
}
}
De feature_management
sectie van het json-document wordt door de conventie gebruikt om instellingen voor functievlagken te laden. Functievlagobjecten moeten worden vermeld in de feature_flags
matrix onder de feature_management
sectie. In de bovenstaande sectie zien we dat we drie verschillende functies hebben opgegeven. Een functievlag heeft id
en enabled
eigenschappen. Dit id
is de naam die wordt gebruikt om de functievlag te identificeren en ernaar te verwijzen. De enabled
eigenschap geeft de ingeschakelde status van de functievlag aan. Een functie is UITGESCHAKELD als enabled
deze onwaar is. Als enabled
waar is, is de status van de functie afhankelijk van de conditions
. Als er geen conditions
is, is de functie INGESCHAKELD. Als er wel conditions
en ze worden ontmoet, is de functie ingeschakeld. Als er wel conditions
en niet aan hen wordt voldaan, is de functie uitgeschakeld. De conditions
eigenschap declareert de voorwaarden die worden gebruikt om de functie dynamisch in te schakelen. Functies definiëren hun functiefilters in de client_filters
matrix. FeatureV
hiermee geeft u een functiefilter met de naam Microsoft.TimeWindow
. Dit is een voorbeeld van een configureerbaar functiefilter. In het voorbeeld zien we dat het filter een Parameters
eigenschap heeft. Dit wordt gebruikt om het filter te configureren. In dit geval worden de begin- en eindtijden voor de functie geconfigureerd om actief te zijn.
Geavanceerd: Het gebruik van dubbele punt ':' is verboden in functievlagnamen.
RequirementType
De requirement_type
eigenschap van conditions
wordt gebruikt om te bepalen of de filters moeten worden gebruikt Any
of All
logica bij het evalueren van de status van een functie. Als requirement_type
dit niet is opgegeven, is Any
de standaardwaarde .
Any
betekent dat slechts één filter waar moet worden geëvalueerd om de functie in te schakelen.All
betekent dat elk filter waar moet evalueren om de functie in te schakelen.
Een requirement_type
van All
wijzigingen in de doorkruising. Als er geen filter is, wordt de functie eerst uitgeschakeld. Als er filters zijn, worden de functiefilters doorkruist totdat een van de filters besluit dat de functie moet worden uitgeschakeld. Als er geen filter wordt aangegeven dat de functie moet worden uitgeschakeld, wordt deze als ingeschakeld beschouwd.
{
"id": "FeatureW",
"enabled": true,
"conditions": {
"requirement_type": "All",
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
},
{
"name": "Microsoft.Percentage",
"parameters": {
"Value": "50"
}
}
]
}
}
In het bovenstaande voorbeeld geeft u een requirement_type
vanAll
, FeatureW
wat betekent dat alle filters waar moeten zijn om de functie in te schakelen. In dit geval wordt de functie ingeschakeld voor 50% van de gebruikers tijdens het opgegeven tijdvenster.
.NET-schema voor functiebeheer
In eerdere versies was het primaire schema voor de functiebeheerbibliotheek de .NET feature management schema
. Vanaf v4.0.0 worden nieuwe functies, waaronder varianten en telemetrie, niet ondersteund voor het .NET-functiebeheerschema.
Notitie
Als er een functievlagdeclaratie is die zowel in de secties als in de feature_management
FeatureManagement
secties te vinden is, wordt de declaratie van de feature_management
sectie aangenomen.
Verbruik
De basisvorm van functiebeheer is controleren of een functievlag is ingeschakeld en vervolgens acties uitvoert op basis van het resultaat. Dit wordt gedaan via de IFeatureManager
IsEnabledAsync
methode.
…
IFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
// Do something
}
Serviceregistratie
Functiebeheer is afhankelijk van afhankelijkheidsinjectie van .NET Core. We kunnen de functiebeheerservices registreren met behulp van standaardconventies.
using Microsoft.FeatureManagement;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddFeatureManagement();
}
}
De functiebeheerder haalt standaard de configuratie van functievlagken op uit de sectie 'FeatureManagement' van de .NET Core-configuratiegegevens. Als de sectie 'FeatureManagement' niet bestaat, wordt de configuratie als leeg beschouwd.
Notitie
U kunt ook opgeven dat de configuratie van de functievlag moet worden opgehaald uit een andere configuratiesectie door de sectie door te geven aan AddFeatureManagement
. In het volgende voorbeeld wordt aan de functiebeheerder gelezen uit een andere sectie met de naam 'MyFeatureFlags':
services.AddFeatureManagement(configuration.GetSection("MyFeatureFlags"));
Afhankelijkheidsinjectie
Wanneer u de functiebeheerbibliotheek met MVC gebruikt, kunt u deze IFeatureManager
verkrijgen via afhankelijkheidsinjectie.
public class HomeController : Controller
{
private readonly IFeatureManager _featureManager;
public HomeController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
}
Scoped Feature Management Services
De AddFeatureManagement
methode voegt functiesbeheerservices toe als singletons binnen de toepassing, maar er zijn scenario's waarin het mogelijk nodig is dat functiebeheerservices worden toegevoegd als scoped services. Gebruikers willen bijvoorbeeld functiefilters gebruiken die scoped services gebruiken voor contextinformatie. In dit geval moet de AddScopedFeatureManagement
methode worden gebruikt. Dit zorgt ervoor dat functiebeheerservices, inclusief functiefilters, worden toegevoegd als scoped services.
services.AddScopedFeatureManagement();
ASP.NET Kernintegratie
De bibliotheek voor functiebeheer biedt functionaliteit in ASP.NET Core en MVC om algemene functievlagscenario's in webtoepassingen mogelijk te maken. Deze mogelijkheden zijn beschikbaar door te verwijzen naar het NuGet-pakket Microsoft.FeatureManagement.AspNetCore .
Controllers en acties
MVC-controller en -acties kunnen vereisen dat een bepaalde functie, of een van een lijst met functies, wordt ingeschakeld om uit te voeren. U kunt dit doen met behulp van een FeatureGateAttribute
, die u kunt vinden in de Microsoft.FeatureManagement.Mvc
naamruimte.
[FeatureGate("FeatureX")]
public class HomeController : Controller
{
…
}
Het HomeController
bovenstaande is gated door "FeatureX". FeatureX moet zijn ingeschakeld voordat een actie HomeController
kan worden uitgevoerd.
[FeatureGate("FeatureX")]
public IActionResult Index()
{
return View();
}
Voor de Index
bovenstaande MVC-actie moet FeatureX worden ingeschakeld voordat deze kan worden uitgevoerd.
Afhandeling van uitgeschakelde acties
Wanneer een MVC-controller of -actie wordt geblokkeerd omdat geen van de functies die worden opgegeven, is ingeschakeld, wordt een geregistreerde IDisabledFeaturesHandler
aangeroepen. Standaard wordt een minimalistische handler geregistreerd die HTTP 404 retourneert. Dit kan worden overschreven met behulp van de functievlagmen bij het IFeatureManagementBuilder
registreren van functievlagmen.
public interface IDisabledFeaturesHandler
{
Task HandleDisabledFeature(IEnumerable<string> features, ActionExecutingContext context);
}
Weergave
In MVC-weergavetags <feature>
kunnen tags worden gebruikt om inhoud voorwaardelijk weer te geven op basis van of een functie al dan niet is ingeschakeld.
<feature name="FeatureX">
<p>This can only be seen if 'FeatureX' is enabled.</p>
</feature>
U kunt ook de evaluatie van de taghelper om inhoud weer te geven wanneer een functie of set functies is uitgeschakeld. Door in het onderstaande voorbeeld in te stellen negate="true"
, wordt de inhoud alleen weergegeven als FeatureX
deze is uitgeschakeld.
<feature negate="true" name="FeatureX">
<p>This can only be seen if 'FeatureX' is disabled.</p>
</feature>
De <feature>
tag kan verwijzen naar meerdere functies door een door komma's gescheiden lijst met functies in het name
kenmerk op te geven.
<feature name="FeatureX,FeatureY">
<p>This can only be seen if 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>
Standaard moeten alle vermelde functies zijn ingeschakeld om de functietag weer te geven. Dit gedrag kan worden overschreven door het requirement
kenmerk toe te voegen, zoals te zien is in het onderstaande voorbeeld.
<feature name="FeatureX,FeatureY" requirement="Any">
<p>This can only be seen if either 'FeatureX' or 'FeatureY' or both are enabled.</p>
</feature>
In MVC-weergaven <feature>
kunnen tags worden gebruikt om inhoud voorwaardelijk weer te geven op basis van of een functie is ingeschakeld of of een specifieke variant van een functie is toegewezen. Zie de sectie varianten voor meer informatie.
<feature name="FeatureX">
<p>This can only be seen if 'FeatureX' is enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha">
<p>This can only be seen if variant 'Alpha' of 'FeatureX' is assigned.</p>
</feature>
U kunt ook de evaluatie van de taghelper om inhoud weer te geven wanneer een functie of set functies is uitgeschakeld. Door in het onderstaande voorbeeld in te stellen negate="true"
, wordt de inhoud alleen weergegeven als FeatureX
deze is uitgeschakeld.
<feature negate="true" name="FeatureX">
<p>This can only be seen if 'FeatureX' is disabled.</p>
</feature>
<feature negate="true" name="FeatureX" variant="Alpha">
<p>This can only be seen if variant 'Alpha' of 'FeatureX' isn't assigned.</p>
</feature>
De <feature>
tag kan verwijzen naar meerdere functies/varianten door een door komma's gescheiden lijst met functies/varianten in het name
/variant
kenmerk op te geven.
<feature name="FeatureX,FeatureY">
<p>This can only be seen if 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha,Beta">
<p>This can only be seen if variant 'Alpha' or 'Beta' of 'FeatureX' is assigned.</p>
</feature>
Notitie
Als variant
dit is opgegeven, moet er slechts één functie worden opgegeven.
Standaard moeten alle vermelde functies zijn ingeschakeld om de functietag weer te geven. Dit gedrag kan worden overschreven door het requirement
kenmerk toe te voegen, zoals te zien is in het onderstaande voorbeeld.
Notitie
Als er een requirement
van And
wordt gebruikt in combinatie met variant
een fout, wordt er een fout gegenereerd, omdat er nooit meerdere varianten kunnen worden toegewezen.
<feature name="FeatureX,FeatureY" requirement="Any">
<p>This can only be seen if either 'FeatureX' or 'FeatureY' or both are enabled.</p>
</feature>
Voor de <feature>
tag is een taghulp vereist. U kunt dit doen door de tag-helper voor functiebeheer toe te voegen aan het bestand ViewImports.cshtml .
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
MVC-filters
MVC-actiefilters kunnen worden ingesteld om voorwaardelijk uit te voeren op basis van de status van een functie. Dit wordt gedaan door MVC-filters op een functiebewuste manier te registreren.
De functiebeheerpijplijn ondersteunt asynchrone MVC-actiefilters, die worden geïmplementeerd IAsyncActionFilter
.
services.AddMvc(o =>
{
o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});
Met de bovenstaande code wordt een MVC-filter met de naam SomeMvcFilter
toegevoegd. Dit filter wordt alleen geactiveerd in de MVC-pijplijn als 'FeatureX' is ingeschakeld.
Razor Pages
MVC Razor-pagina's kunnen vereisen dat een bepaalde functie, of een van een lijst met functies, is ingeschakeld om uit te voeren. U kunt dit doen met behulp van een FeatureGateAttribute
, die u kunt vinden in de Microsoft.FeatureManagement.Mvc
naamruimte.
[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Met de bovenstaande code stelt u een Razor-pagina in om de functie 'FeatureX' in te schakelen. Als de functie niet is ingeschakeld, genereert de pagina een HTTP 404-resultaat (NotFound).
Bij gebruik op Razor-pagina's moet de FeatureGateAttribute
pagina-handler op het type pagina-handler worden geplaatst. Het kan niet worden geplaatst op afzonderlijke handlermethoden.
Toepassingsgebouw
De bibliotheek voor functiebeheer kan worden gebruikt om toepassingsbranches en middleware toe te voegen die voorwaardelijk worden uitgevoerd op basis van de functiestatus.
app.UseMiddlewareForFeature<ThirdPartyMiddleware>("FeatureX");
Met de bovenstaande aanroep voegt de toepassing een middlewareonderdeel toe dat alleen wordt weergegeven in de aanvraagpijplijn als de functie FeatureX is ingeschakeld. Als de functie tijdens runtime is ingeschakeld/uitgeschakeld, kan de middleware-pijplijn dynamisch worden gewijzigd.
Dit bouwt voort op de algemenere mogelijkheid om de hele toepassing te vertakken op basis van een functie.
app.UseForFeature(featureName, appBuilder =>
{
appBuilder.UseMiddleware<T>();
});
Een functiefilter implementeren
Het maken van een functiefilter biedt een manier om functies in te schakelen op basis van criteria die u definieert. Als u een functiefilter wilt implementeren, moet de IFeatureFilter
interface worden geïmplementeerd. IFeatureFilter
heeft één methode met de naam EvaluateAsync
. Wanneer een functie aangeeft dat deze kan worden ingeschakeld voor een functiefilter, wordt de EvaluateAsync
methode aangeroepen. Als EvaluateAsync
de functie wordt geretourneerd true
, betekent dit dat de functie moet worden ingeschakeld.
Het volgende codefragment laat zien hoe u een aangepast functiefilter MyCriteriaFilter
toevoegt.
services.AddFeatureManagement()
.AddFeatureFilter<MyCriteriaFilter>();
Functiefilters worden geregistreerd door aan te roepen AddFeatureFilter<T>
op de IFeatureManagementBuilder
geretourneerde functie AddFeatureManagement
. Deze functiefilters hebben toegang tot de services die bestaan in de serviceverzameling die is gebruikt om functievlagmen toe te voegen. Afhankelijkheidsinjectie kan worden gebruikt om deze services op te halen.
Notitie
Wanneer naar filters wordt verwezen in instellingen voor functievlagken (bijvoorbeeld appsettings.json), moet het filtergedeelte van de typenaam worden weggelaten. Zie de Filter Alias Attribute
sectie voor meer informatie.
Geparameteriseerde functiefilters
Sommige functiefilters vereisen parameters om te bepalen of een functie moet worden ingeschakeld of niet. Een browserfunctiefilter kan bijvoorbeeld een functie inschakelen voor een bepaalde set browsers. Het kan gewenst zijn dat Edge- en Chrome-browsers een functie inschakelen, terwijl Firefox dat niet doet. Hiervoor kan een functiefilter worden ontworpen om parameters te verwachten. Deze parameters zouden worden opgegeven in de functieconfiguratie en in code toegankelijk zijn via de FeatureFilterEvaluationContext
parameter van IFeatureFilter.EvaluateAsync
.
public class FeatureFilterEvaluationContext
{
/// <summary>
/// The name of the feature being evaluated.
/// </summary>
public string FeatureName { get; set; }
/// <summary>
/// The settings provided for the feature filter to use when evaluating whether the feature should be enabled.
/// </summary>
public IConfiguration Parameters { get; set; }
}
FeatureFilterEvaluationContext
heeft een eigenschap met de naam Parameters
. Deze parameters vertegenwoordigen een onbewerkte configuratie die het functiefilter kan gebruiken om te bepalen hoe de functie moet worden ingeschakeld of niet. Als u het browserfunctiefilter opnieuw wilt gebruiken als voorbeeld, kan het filter een Parameters
set toegestane browsers extraheren die voor de functie worden opgegeven en vervolgens controleren of de aanvraag wordt verzonden vanuit een van deze browsers.
[FilterAlias("Browser")]
public class BrowserFilter : IFeatureFilter
{
…
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
{
BrowserFilterSettings settings = context.Parameters.Get<BrowserFilterSettings>() ?? new BrowserFilterSettings();
//
// Here we would use the settings and see if the request was sent from any of BrowserFilterSettings.AllowedBrowsers
}
}
Kenmerk Filteralias
Wanneer een functiefilter is geregistreerd voor een functievlag, is de alias die wordt gebruikt in de configuratie de naam van het functiefiltertype met het filterachtervoegsel , indien van toepassing, verwijderd. Dit wordt bijvoorbeeld MyCriteriaFilter
MyCriteria genoemd in de configuratie.
"MyFeature": {
"EnabledFor": [
{
"Name": "MyCriteria"
}
]
}
Dit kan worden overschreven met behulp van de FilterAliasAttribute
. Een functiefilter kan worden ingericht met dit kenmerk om de naam te declareren die moet worden gebruikt in de configuratie om te verwijzen naar dit functiefilter binnen een functievlag.
Ontbrekende functiefilters
Als een functie is geconfigureerd voor een specifiek functiefilter en dat functiefilter niet is geregistreerd, wordt er een uitzondering gegenereerd wanneer de functie wordt geëvalueerd. De uitzondering kan worden uitgeschakeld met behulp van de opties voor functiebeheer.
services.Configure<FeatureManagementOptions>(options =>
{
options.IgnoreMissingFeatureFilters = true;
});
HttpContext gebruiken
Functiefilters kunnen evalueren of een functie moet worden ingeschakeld op basis van de eigenschappen van een HTTP-aanvraag. Dit wordt uitgevoerd door de HTTP-context te controleren. Een functiefilter kan een verwijzing naar de HTTP-context krijgen door een IHttpContextAccessor
via afhankelijkheidsinjectie te verkrijgen.
public class BrowserFilter : IFeatureFilter
{
private readonly IHttpContextAccessor _httpContextAccessor;
public BrowserFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
}
De IHttpContextAccessor
moet worden toegevoegd aan de container voor afhankelijkheidsinjectie bij het opstarten, zodat deze beschikbaar is. Deze kan worden geregistreerd in de IServiceCollection
volgende methode.
public void ConfigureServices(IServiceCollection services)
{
…
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
…
}
Geavanceerd: IHttpContextAccessor
/HttpContext
mag niet worden gebruikt in de Razor-onderdelen van Blazor-apps aan de serverzijde. De aanbevolen methode voor het doorgeven van http-context in Blazor-apps is het kopiëren van de gegevens naar een scoped service. Voor Blazor-apps AddScopedFeatureManagement
moet worden gebruikt om de functiebeheerservices te registreren. Zie de Scoped Feature Management Services
sectie voor meer informatie.
Een context opgeven voor functie-evaluatie
In consoletoepassingen is er geen omgevingscontext zoals HttpContext
die functiefilters kunnen verkrijgen en gebruiken om te controleren of een functie moet worden ingeschakeld of uitgeschakeld. In dit geval moeten toepassingen een object opgeven dat een context vertegenwoordigt in het functiebeheersysteem voor gebruik door functiefilters. Dit wordt gedaan met behulp van IFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext)
. Het appContext-object dat aan het functiebeheer wordt verstrekt, kan worden gebruikt door functiefilters om de status van een functie te evalueren.
MyAppContext context = new MyAppContext
{
AccountId = current.Id;
}
if (await featureManager.IsEnabledAsync(feature, context))
{
…
}
Contextuele functiefilters
Contextuele functiefilters implementeren de IContextualFeatureFilter<TContext>
interface. Deze speciale functiefilters kunnen profiteren van de context die wordt doorgegeven wanneer IFeatureManager.IsEnabledAsync<TContext>
deze wordt aangeroepen. De TContext
typeparameter in IContextualFeatureFilter<TContext>
beschrijft welk contexttype het filter kan verwerken. Hierdoor kan de ontwikkelaar van een contextueel functiefilter beschrijven wat vereist is voor degenen die het willen gebruiken. Omdat elk type een afstammeling van het object is, kan een filter dat wordt geïmplementeerd IContextualFeatureFilter<object>
, worden aangeroepen voor elke opgegeven context. Als u een voorbeeld van een specifieker contextafhankelijk functiefilter wilt illustreren, kunt u een functie overwegen die is ingeschakeld als een account zich in een geconfigureerde lijst met ingeschakelde accounts bevindt.
public interface IAccountContext
{
string AccountId { get; set; }
}
[FilterAlias("AccountId")]
class AccountIdFilter : IContextualFeatureFilter<IAccountContext>
{
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext featureEvaluationContext, IAccountContext accountId)
{
//
// Evaluate if the feature should be on with the help of the provided IAccountContext
}
}
We kunnen zien dat er AccountIdFilter
een object is vereist dat IAccountContext
wordt geïmplementeerd om de status van een functie te kunnen evalueren. Wanneer u dit functiefilter gebruikt, moet de aanroeper ervoor zorgen dat het doorgegeven object wordt IAccountContext
geïmplementeerd.
Notitie
Er kan slechts één filterinterface voor functies worden geïmplementeerd door één type. Als u een functiefilter probeert toe te voegen waarmee meer dan één functiefilterinterface wordt geïmplementeerd, resulteert dit in een ArgumentException
.
Contextuele en niet-contextuele filters gebruiken met dezelfde alias
Filters van IFeatureFilter
en IContextualFeatureFilter
kunnen dezelfde alias delen. U kunt met name één filteralias delen door 0 of 1 IFeatureFilter
en 0 of N IContextualFeatureFilter<ContextType>
, zolang er maximaal één van toepassingsfilters voor ContextType
is.
In de volgende passage wordt beschreven hoe u een filter selecteert wanneer contextuele en niet-contextuele filters van dezelfde naam zijn geregistreerd in een toepassing.
Stel dat u een niet-contextueel filter hebt aangeroepen FilterA
en twee contextuele filters FilterB
en FilterC die respectievelijk context accepteren en TypeC
contexten accepterenTypeB
. Alle drie de filters delen dezelfde alias SharedFilterName
.
U hebt ook een functievlag MyFeature
die gebruikmaakt van het functiefilter SharedFilterName
in de configuratie.
Als alle drie de filters zijn geregistreerd:
- Wanneer u IsEnabledAsync("MyFeature") aanroept, wordt de
FilterA
functievlag gebruikt om de functievlag te evalueren. - Wanneer u IsEnabledAsync("MyFeature", context), als het type context is
TypeB
,FilterB
wordt gebruikt. Als het type context isTypeC
,FilterC
wordt gebruikt. - Wanneer u IsEnabledAsync("MyFeature", context), als het type context is
TypeF
,FilterA
wordt gebruikt.
Ingebouwde functiefilters
Er zijn enkele functiefilters die bij het Microsoft.FeatureManagement
pakket worden geleverd: PercentageFilter
, TimeWindowFilter
en TargetingFilter
ContextualTargetingFilter
. Alle filters, met uitzondering van de TargetingFilter
filters, worden automatisch toegevoegd wanneer functiebeheer per methode wordt geregistreerdAddFeatureManagement
. De TargetingFilter
wordt toegevoegd met de WithTargeting
methode die in de Targeting
onderstaande sectie wordt beschreven.
Elk van de ingebouwde functiefilters heeft zijn eigen parameters. Hier volgt een lijst met functiefilters, samen met voorbeelden.
Microsoft.Percentage
Dit filter biedt de mogelijkheid om een functie in te schakelen op basis van een ingesteld percentage.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.Percentage",
"Parameters": {
"Value": 50
}
}
]
}
Microsoft.TimeWindow
Dit filter biedt de mogelijkheid om een functie in te schakelen op basis van een tijdvenster. Als alleen End
wordt opgegeven, wordt de functie tot die tijd overwogen. Als alleen Start
wordt opgegeven, wordt de functie op alle punten na die tijd overwogen.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
Het tijdvenster kan worden geconfigureerd om periodiek opnieuw te worden uitgevoerd. Dit kan handig zijn voor de scenario's waarbij een functie mogelijk moet worden ingeschakeld tijdens een periode van weinig of hoog verkeer van een dag of bepaalde dagen van een week. Als u het afzonderlijke tijdvenster wilt uitbreiden naar terugkerende tijdvensters, moet de regel voor terugkeerpatroon worden opgegeven in de Recurrence
parameter.
Notitie
Start
en End
moet beide zijn opgegeven om in te schakelen Recurrence
.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "Fri, 22 Mar 2024 20:00:00 GMT",
"End": "Sat, 23 Mar 2024 02:00:00 GMT",
"Recurrence": {
"Pattern": {
"Type": "Daily",
"Interval": 1
},
"Range": {
"Type": "NoEnd"
}
}
}
}
]
}
De Recurrence
instellingen bestaan uit twee delen: Pattern
(hoe vaak het tijdvenster wordt herhaald) en Range
(voor hoe lang het terugkeerpatroon wordt herhaald).
Terugkeerpatroon
Er zijn twee mogelijke terugkeerpatroontypen: Daily
en Weekly
. Een tijdvenster kan bijvoorbeeld 'elke dag', 'elke drie dagen', 'elke maandag' of 'elke andere vrijdag' herhalen.
Afhankelijk van het type zijn bepaalde velden van de Pattern
velden vereist, optioneel of genegeerd.
Daily
Het dagelijkse terugkeerpatroon zorgt ervoor dat het tijdvenster wordt herhaald op basis van een aantal dagen tussen elke gebeurtenis.
Eigenschappen Relevantie Beschrijving Type Vereist Moet worden ingesteld op Daily
.Interval Optioneel Hiermee geeft u het aantal dagen tussen elke instantie. De standaardwaarde is 1. Weekly
Het wekelijkse terugkeerpatroon zorgt ervoor dat het tijdvenster op dezelfde dag of dagen van de week wordt herhaald, op basis van het aantal weken tussen elke set exemplaren.
Eigenschappen Relevantie Beschrijving Type Vereist Moet worden ingesteld op Weekly
.DaysOfWeek Vereist Hiermee geeft u op op welke dagen van de week de gebeurtenis plaatsvindt. Interval Optioneel Hiermee geeft u het aantal weken tussen elke set exemplaren. De standaardwaarde is 1. FirstDayOfWeek Optioneel Hiermee geeft u op welke dag wordt beschouwd als de eerste dag van de week. De standaardwaarde is Sunday
.In het volgende voorbeeld wordt het tijdvenster elke andere maandag en dinsdag herhaald
"Pattern": { "Type": "Weekly", "Interval": 2, "DaysOfWeek": ["Monday", "Tuesday"] }
Notitie
Start
moet een geldig eerste exemplaar zijn dat past bij het terugkeerpatroon. Bovendien kan de duur van het tijdvenster niet langer zijn dan hoe vaak het duurt. Het is bijvoorbeeld ongeldig dat er elke dag een tijdvenster van 25 uur opnieuw optreedt.
Terugkeerpatroon
Er zijn drie mogelijke terugkeerbereiktypen: NoEnd
en EndDate
Numbered
.
NoEnd
Het
NoEnd
bereik zorgt ervoor dat het terugkeerpatroon voor onbepaalde tijd plaatsvindt.Eigenschappen Relevantie Beschrijving Type Vereist Moet worden ingesteld op NoEnd
.EndDate
Het
EndDate
bereik zorgt ervoor dat het tijdvenster plaatsvindt op alle dagen die passen bij het toepasselijke patroon tot de einddatum.Eigenschappen Relevantie Beschrijving Type Vereist Moet worden ingesteld op EndDate
.EndDate Vereist Hiermee geeft u de datum/tijd op om het toepassen van het patroon te stoppen. Zolang de begintijd van de laatste gebeurtenis vóór de einddatum valt, mag de eindtijd van die gebeurtenis langer duren. In het volgende voorbeeld wordt het tijdvenster elke dag herhaald totdat het laatste exemplaar plaatsvindt op 1 april 2024.
"Start": "Fri, 22 Mar 2024 18:00:00 GMT", "End": "Fri, 22 Mar 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Daily", "Interval": 1 }, "Range": { "Type": "EndDate", "EndDate": "Mon, 1 Apr 2024 20:00:00 GMT" } }
Numbered
Het
Numbered
bereik zorgt ervoor dat het tijdvenster een vast aantal keren voorkomt (op basis van het patroon).Eigenschappen Relevantie Beschrijving Type Vereist Moet worden ingesteld op Numbered
.NumberOfOccurrences Vereist Hiermee geeft u het aantal exemplaren op. In het volgende voorbeeld wordt het tijdvenster op maandag en dinsdag herhaald totdat er respectievelijk drie gebeurtenissen plaatsvinden, die respectievelijk plaatsvinden op 1(Mon), 2(Tue) en 8(Ma).
"Start": "Mon, 1 Apr 2024 18:00:00 GMT", "End": "Mon, 1 Apr 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Weekly", "Interval": 1, "DaysOfWeek": ["Monday", "Tuesday"] }, "Range": { "Type": "Numbered", "NumberOfOccurrences": 3 } }
Als u een terugkeerregel wilt maken, moet u zowel als Pattern
Range
. Elk patroontype kan werken met elk bereiktype.
Geavanceerd: De tijdzone-offset van de Start
eigenschap wordt toegepast op de terugkeerpatrooninstellingen.
Microsoft.Targeting
Dit filter biedt de mogelijkheid om een functie in te schakelen voor een doelgroep. Een uitgebreide uitleg van targeting wordt uitgelegd in de onderstaande sectie over targeting . De filterparameters bevatten een Audience
object dat gebruikers, groepen, uitgesloten gebruikers/groepen en een standaardpercentage van de gebruikersbasis beschrijft die toegang tot de functie moet hebben. Elk groepsobject dat in de Groups
sectie wordt vermeld, moet ook opgeven welk percentage van de leden van de groep toegang moet hebben. Als een gebruiker is opgegeven in de Exclusion
sectie, rechtstreeks of als de gebruiker zich in een uitgesloten groep bevindt, is de functie uitgeschakeld. Als een gebruiker in de Users
sectie rechtstreeks is opgegeven of als de gebruiker zich in het opgenomen percentage van een van de groeps-implementaties bevindt, of als de gebruiker in het standaard rolloutpercentage valt, heeft die gebruiker de functie ingeschakeld.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.Targeting",
"Parameters": {
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
},
{
"Name": "Ring1",
"RolloutPercentage": 50
}
],
"DefaultRolloutPercentage": 20,
"Exclusion": {
"Users": [
"Ross"
],
"Groups": [
"Ring2"
]
}
}
}
}
]
}
Naamruimten van functiefilteralias
Alle ingebouwde functiefilteralias bevinden zich in de Microsoft
functiefilternaamruimte. Dit is om conflicten met andere functiefilters te voorkomen die dezelfde alias kunnen delen. De segmenten van een functiefilternaamruimte worden gesplitst door het teken '.'. Er kan naar een functiefilter worden verwezen door de volledig gekwalificeerde alias, zoals Microsoft.Percentage
of door het laatste segment dat in het geval van Microsoft.Percentage
is Percentage
.
Targeten
Het doel is een strategie voor functiebeheer waarmee ontwikkelaars geleidelijk nieuwe functies kunnen implementeren in hun gebruikersbestand. De strategie is gebaseerd op het concept van het richten van een set gebruikers die bekend staan als de doelgroep. Een doelgroep bestaat uit specifieke gebruikers, groepen, uitgesloten gebruikers/groepen en een aangewezen percentage van het gehele gebruikersbestand. De groepen die in de doelgroep zijn opgenomen, kunnen verder worden onderverdeeld in percentages van hun totale leden.
In de volgende stappen ziet u een voorbeeld van een progressieve implementatie voor een nieuwe bètafunctie:
- Individuele gebruikers Jeff en Alicia krijgen toegang tot de bètaversie
- Een andere gebruiker, Mark, vraagt zich aan te aanmelden en is inbegrepen.
- Twintig procent van een groep die bekend staat als Ring1-gebruikers, worden opgenomen in de bètaversie.
- Het aantal ring1-gebruikers dat in de bètaversie is opgenomen, wordt tot 100 procent opgestoten.
- Vijf procent van de gebruikersbasis is opgenomen in de bètaversie.
- Het implementatiepercentage wordt maximaal 100 procent opgestoten en de functie wordt volledig uitgerold.
Deze strategie voor het implementeren van een functie is ingebouwd in de bibliotheek via het meegeleverde Microsoft.Targeting-functiefilter .
Targeting in een webtoepassing
Een voorbeeldwebtoepassing die gebruikmaakt van het doelfunctiefilter is beschikbaar in het voorbeeldproject FeatureFlagDemo .
Als u de TargetingFilter
toepassing in een toepassing wilt gaan gebruiken, moet deze net als elk ander functiefilter worden toegevoegd aan de serviceverzameling van de toepassing. In tegenstelling tot andere ingebouwde filters is het TargetingFilter
afhankelijk van een andere service die moet worden toegevoegd aan de serviceverzameling van de toepassing. Die service is een ITargetingContextAccessor
.
Microsoft.FeatureManagement.AspNetCore
biedt een standaard implementatie ITargetingContextAccessor
waarvan doelgegevens worden geëxtraheerd uit een aanvraag HttpContext
. U kunt de standaardcontexttoegangsor gebruiken bij het instellen van doelen door gebruik te maken van de niet-algemene WithTargeting
overbelasting op de IFeatureManagementBuilder
.
De standaardinstelling voor contexttoegangsbeheer en TargetingFilter
worden geregistreerd door aan te roepen WithTargeting
op de IFeatureManagementBuilder
.
services.AddFeatureManagement()
.WithTargeting();
U kunt ook een aangepaste implementatie registreren voor ITargetingContextAccessor
en TargetingFilter
door aan te roepen WithTargeting<T>
. Hier volgt een voorbeeld van het instellen van functiebeheer in een webtoepassing voor gebruik TargetingFilter
met een aangeroepen ExampleTargetingContextAccessor
implementatieITargetingContextAccessor
.
services.AddFeatureManagement()
.WithTargeting<ExampleTargetingContextAccessor>();
ITargetingContextAccessor
Als u de TargetingFilter
in een webtoepassing wilt gebruiken, is een implementatie van ITargetingContextAccessor
vereist. Dit komt doordat wanneer een doelevaluatie wordt uitgevoerd, contextuele informatie zoals welke gebruiker momenteel wordt geëvalueerd, nodig is. Deze informatie staat bekend als de TargetingContext
. Verschillende toepassingen kunnen deze informatie uit verschillende plaatsen extraheren. Enkele veelvoorkomende voorbeelden van waar een toepassing de doelcontext kan ophalen, zijn de HTTP-context van de aanvraag of een database.
Een voorbeeld waarmee doelcontextinformatie wordt geëxtraheerd uit de HTTP-context van de toepassing, is het DefaultHttpTargetingContextAccessor
pakket Microsoft.FeatureManagement.AspNetCore
. Het extraheert doelgegevens uit HttpContext.User
. UserId
gegevens worden uit het Identity.Name
veld geëxtraheerd en Groups
informatie wordt geëxtraheerd uit claims van het type Role
. Deze implementatie is afhankelijk van het gebruik van IHttpContextAccessor
, dat hier wordt besproken.
Doel in een consoletoepassing
Het doelfilter is afhankelijk van een doelcontext om te evalueren of een functie moet worden ingeschakeld. Deze doelcontext bevat informatie zoals welke gebruiker momenteel wordt geëvalueerd en in welke groepen de gebruiker zich bevindt. In consoletoepassingen is er doorgaans geen omgevingscontext beschikbaar om deze informatie naar het doelfilter te laten stromen, zodat deze rechtstreeks moet worden doorgegeven wanneer FeatureManager.IsEnabledAsync
deze wordt aangeroepen. Dit wordt ondersteund met behulp van de ContextualTargetingFilter
. Toepassingen die de doelcontext naar de functiebeheerder moeten zweven, moeten dit gebruiken in plaats van de TargetingFilter.
Aangezien ContextualTargetingFilter
dit een IContextualTargetingFilter<ITargetingContext>
is, moet een implementatie van ITargetingContext
deze worden doorgegeven IFeatureManager.IsEnabledAsync
om een functie te kunnen evalueren en in te schakelen.
IFeatureManager fm;
…
// userId and groups defined somewhere earlier in application
TargetingContext targetingContext = new TargetingContext
{
UserId = userId,
Groups = groups
};
await fm.IsEnabledAsync(featureName, targetingContext);
De ContextualTargetingFilter
functiefilteralias Microsoft.Targeting wordt nog steeds gebruikt, dus de configuratie voor dit filter is consistent met wat in die sectie wordt vermeld.
Een voorbeeld waarin de ContextualTargetingFilter
in een consoletoepassing wordt gebruikt, is beschikbaar in het voorbeeldproject TargetingConsoleApp .
Opties voor evaluatie
Er zijn opties beschikbaar om aan te passen hoe doelevaluatie wordt uitgevoerd voor alle functies. Deze opties kunnen worden geconfigureerd bij het instellen van functiebeheer.
services.Configure<TargetingEvaluationOptions>(options =>
{
options.IgnoreCase = true;
});
Uitsluiting instellen
Bij het definiëren van een doelgroep kunnen gebruikers en groepen worden uitgesloten van de doelgroep. Dit is handig wanneer een functie wordt geïmplementeerd voor een groep gebruikers, maar een paar gebruikers of groepen moeten worden uitgesloten van de implementatie. Uitsluiting wordt gedefinieerd door een lijst met gebruikers en groepen toe te voegen aan de Exclusion
eigenschap van de doelgroep.
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
}
],
"DefaultRolloutPercentage": 0
"Exclusion": {
"Users": [
"Mark"
]
}
}
In het bovenstaande voorbeeld is de functie ingeschakeld voor gebruikers met de naam Jeff
en Alicia
. Het is ook ingeschakeld voor gebruikers in de groep met de naam Ring0
. Als de gebruiker echter de naam Mark
heeft, is de functie uitgeschakeld, ongeacht of deze zich in de groep bevinden Ring0
of niet. Uitsluitingen hebben voorrang op de rest van het doelfilter.
Varianten
Wanneer er nieuwe functies aan een toepassing worden toegevoegd, kan het gebeuren dat een functie meerdere verschillende voorgestelde ontwerpopties heeft. Een algemene oplossing voor het bepalen van een ontwerp is een vorm van A/B-tests, waarbij een andere versie van de functie moet worden verstrekt aan verschillende segmenten van de gebruikersbasis en een versie wordt gekozen op basis van gebruikersinteractie. In deze bibliotheek is deze functionaliteit ingeschakeld door verschillende configuraties van een functie met varianten weer te geven.
Met varianten kan een functievlag meer worden dan een eenvoudige aan/uit-vlag. Een variant vertegenwoordigt een waarde van een functievlag die een tekenreeks, een getal, een Booleaanse waarde of zelfs een configuratieobject kan zijn. Een functievlag die varianten declareert, moet definiëren onder welke omstandigheden elke variant moet worden gebruikt, wat uitgebreider wordt behandeld in de sectie Varianten toewijzen .
public class Variant
{
/// <summary>
/// The name of the variant.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The configuration of the variant.
/// </summary>
public IConfigurationSection Configuration { get; set; }
}
Varianten verkrijgen
Voor elke functie kan een variant worden opgehaald met behulp van de IVariantFeatureManager
methode.GetVariantAsync
…
IVariantFeatureManager featureManager;
…
Variant variant = await featureManager.GetVariantAsync(MyFeatureFlags.FeatureU, CancellationToken.None);
IConfigurationSection variantConfiguration = variant.Configuration;
// Do something with the resulting variant and its configuration
Zodra een variant is opgehaald, kan de configuratie van een variant rechtstreeks worden gebruikt als een IConfigurationSection
van de eigenschap van Configuration
de variant. Een andere optie is om de configuratie te binden aan een object met behulp van . Het configuratiebindingspatroon van NET.
IConfigurationSection variantConfiguration = variant.Configuration;
MyFeatureSettings settings = new MyFeatureSettings();
variantConfiguration.Bind(settings);
De geretourneerde variant is afhankelijk van de gebruiker die momenteel wordt geëvalueerd en die informatie wordt verkregen van een exemplaar van TargetingContext
. Deze context kan worden doorgegeven bij het aanroepen GetVariantAsync
of kan automatisch worden opgehaald uit een implementatie van ITargetingContextAccessor
als deze is geregistreerd.
Declaratie van variantfunctievlag
In vergelijking met normale functievlagmen hebben variantfunctievlagmen twee extra eigenschappen: variants
en allocation
. De variants
eigenschap is een matrix die de varianten bevat die voor deze functie zijn gedefinieerd. De allocation
eigenschap definieert hoe deze varianten moeten worden toegewezen voor de functie. Net als bij het declareren van normale functievlagmen kunt u variantfunctievlagmen instellen in een json-bestand. Hier volgt een voorbeeld van een variantfunctievlag.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"default_when_enabled": "Small",
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
]
},
"variants": [
{
"name": "Big"
},
{
"name": "Small"
}
]
}
]
}
}
Varianten definiëren
Elke variant heeft twee eigenschappen: een naam en een configuratie. De naam wordt gebruikt om te verwijzen naar een specifieke variant en de configuratie is de waarde van die variant. De configuratie kan worden ingesteld met behulp van configuration_value
de eigenschap. configuration_value
is een inlineconfiguratie die een tekenreeks, getal, Booleaanse waarde of configuratieobject kan zijn. Als configuration_value
dit niet is opgegeven, is de eigenschap van Configuration
de geretourneerde variant null.
Er wordt een lijst met alle mogelijke varianten gedefinieerd voor elke functie onder de variants
eigenschap.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"variants": [
{
"name": "Big",
"configuration_value": {
"Size": 500
}
},
{
"name": "Small",
"configuration_value": {
"Size": 300
}
}
]
}
]
}
}
Varianten toewijzen
Het proces voor het toewijzen van de varianten van een functie wordt bepaald door de allocation
eigenschap van de functie.
"allocation": {
"default_when_enabled": "Small",
"default_when_disabled": "Small",
"user": [
{
"variant": "Big",
"users": [
"Marsha"
]
}
],
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
],
"percentile": [
{
"variant": "Big",
"from": 0,
"to": 10
}
],
"seed": "13973240"
},
"variants": [
{
"name": "Big",
"configuration_value": "500px"
},
{
"name": "Small",
"configuration_value": "300px"
}
]
De allocation
instelling van een functie heeft de volgende eigenschappen:
Eigenschappen | Beschrijving |
---|---|
default_when_disabled |
Hiermee geeft u op welke variant moet worden gebruikt wanneer een variant wordt aangevraagd terwijl de functie wordt beschouwd als uitgeschakeld. |
default_when_enabled |
Hiermee geeft u op welke variant moet worden gebruikt wanneer een variant wordt aangevraagd terwijl de functie wordt beschouwd als ingeschakeld en er geen andere variant is toegewezen aan de gebruiker. |
user |
Hiermee geeft u een variant en een lijst met gebruikers aan wie die variant moet worden toegewezen. |
group |
Hiermee geeft u een variant en een lijst met groepen. De variant wordt toegewezen als de gebruiker zich in ten minste een van de groepen bevindt. |
percentile |
Hiermee geeft u een variant en een percentagebereik waarin het berekende percentage van de gebruiker moet passen om aan die variant te kunnen worden toegewezen. |
seed |
De waarde waarvoor percentageberekeningen percentile worden uitgevoerd, zijn gebaseerd op. De percentageberekening voor een specifieke gebruiker is hetzelfde voor alle functies als dezelfde seed waarde wordt gebruikt. Als er geen seed is opgegeven, wordt er een standaard-seed gemaakt op basis van de functienaam. |
Als de functie in het bovenstaande voorbeeld niet is ingeschakeld, wijst de functiebeheerder de variant toe die is gemarkeerd als default_when_disabled
de huidige gebruiker. Dit is Small
in dit geval.
Als de functie is ingeschakeld, controleert de functiebeheerder de user
en group
percentile
toewijzingen om een variant toe te wijzen. Als in dit specifieke voorbeeld de gebruiker die wordt geëvalueerd de naam Marsha
heeft, in de groep met de naam Ring1
of als de gebruiker tussen het 0 en 10e percentiel valt, wordt de opgegeven variant toegewezen aan de gebruiker. In dit geval zou al deze de Big
variant retourneren. Als geen van deze toewijzingen overeenkomt, krijgt de gebruiker de default_when_enabled
variant toegewezen.Small
Toewijzingslogica is vergelijkbaar met het functiefilter Microsoft.Targeting , maar er zijn enkele parameters die aanwezig zijn in targeting die niet in toewijzing zijn en omgekeerd. De resultaten van targeting en toewijzing zijn niet gerelateerd.
Notitie
Als u functievarianten wilt toewijzen, moet u zich registreren ITargetingContextAccessor
. Dit kan worden gedaan door de methode aan te WithTargeting<T>
roepen.
Ingeschakelde status overschrijven met een variant
U kunt varianten gebruiken om de ingeschakelde status van een functievlag te overschrijven. Dit biedt varianten de mogelijkheid om de evaluatie van een functievlag uit te breiden. Wanneer u een vlag met varianten aanroept IsEnabled
, controleert de functiebeheerder of de variant die is toegewezen aan de huidige gebruiker is geconfigureerd om het resultaat te overschrijven. Dit wordt gedaan met behulp van de optionele varianteigenschap status_override
. Deze eigenschap is standaard ingesteld op None
, wat betekent dat de variant niet van invloed is op het feit of de vlag wordt beschouwd als ingeschakeld of uitgeschakeld. Enabled
Als u deze instelling status_override
instelt, kan de variant, indien gekozen, een vlag overschrijven die moet worden ingeschakeld. Instelling status_override
om de tegenovergestelde functionaliteit te Disabled
bieden, waardoor de vlag wordt uitgeschakeld wanneer de variant wordt gekozen. Een functie met een enabled
status kan false
niet worden overschreven.
Als u een functievlag met binaire varianten gebruikt, kan de status_override
eigenschap erg nuttig zijn. Hiermee kunt u API's blijven gebruiken, zoals IsEnabledAsync
en FeatureGateAttribute
in uw toepassing, terwijl u profiteert van de nieuwe functies die worden geleverd met varianten, zoals percentieltoewijzing en seed.
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"percentile": [
{
"variant": "On",
"from": 10,
"to": 20
}
],
"default_when_enabled": "Off",
"seed": "Enhanced-Feature-Group"
},
"variants": [
{
"name": "On"
},
{
"name": "Off",
"status_override": "Disabled"
}
]
}
In het bovenstaande voorbeeld is de functie altijd ingeschakeld. Als de huidige gebruiker zich in het berekende percentielbereik van 10 tot 20 bevindt, wordt de On
variant geretourneerd. Anders wordt de Off
variant geretourneerd en omdat status_override
deze gelijk is aan Disabled
, wordt de functie nu als uitgeschakeld beschouwd.
Varianten in afhankelijkheidsinjectie
Variantfunctievlagmen kunnen worden gebruikt in combinatie met afhankelijkheidsinjectie om verschillende implementaties van een service voor verschillende gebruikers weer te geven. Dit wordt bereikt met behulp van de IVariantServiceProvider<TService>
interface.
IVariantServiceProvider<IAlgorithm> algorithmServiceProvider;
...
IAlgorithm forecastAlgorithm = await algorithmServiceProvider.GetServiceAsync(cancellationToken);
In het bovenstaande IVariantServiceProvider<IAlgorithm>
codefragment wordt een implementatie opgehaald van IAlgorithm
de container voor afhankelijkheidsinjectie. De gekozen implementatie is afhankelijk van:
- De functievlag waarmee de
IAlgorithm
service is geregistreerd. - De toegewezen variant voor die functie.
De IVariantServiceProvider<T>
toepassing wordt beschikbaar gesteld door aan te roepen IFeatureManagementBuilder.WithVariantService<T>(string featureName)
. Hieronder vindt u een voorbeeld.
services.AddFeatureManagement()
.WithVariantService<IAlgorithm>("ForecastAlgorithm");
De bovenstaande aanroep maakt IVariantServiceProvider<IAlgorithm>
beschikbaar in de serviceverzameling. Implementaties van IAlgorithm
moeten afzonderlijk worden toegevoegd via een add-methode, zoals services.AddSingleton<IAlgorithm, SomeImplementation>()
. De implementatie hiervan is afhankelijk van IAlgorithm
IVariantServiceProvider
de functievlag van de ForecastAlgorithm
variant. Als er geen implementatie wordt IAlgorithm
toegevoegd aan de serviceverzameling, IVariantServiceProvider<IAlgorithm>.GetServiceAsync()
wordt een taak geretourneerd met een null-resultaat .
{
// The example variant feature flag
"id": "ForecastAlgorithm",
"enabled": true,
"variants": [
{
"Name": "AlgorithmBeta"
},
...
]
}
Kenmerk variantservicealias
[VariantServiceAlias("Beta")]
public class AlgorithmBeta : IAlgorithm
{
...
}
De variantserviceprovider gebruikt de typenamen van implementaties om overeen te komen met de toegewezen variant. Als een variantservice is ingericht met de VariantServiceAliasAttribute
service, moet de naam die in dit kenmerk is gedeclareerd, worden gebruikt in de configuratie om te verwijzen naar deze variantservice.
Telemetrie
Wanneer een wijziging van een functievlag wordt geïmplementeerd, is het vaak belangrijk om het effect ervan op een toepassing te analyseren. Hier volgen bijvoorbeeld enkele vragen die zich kunnen voordoen:
- Zijn mijn vlaggen ingeschakeld/uitgeschakeld zoals verwacht?
- Krijgen doelgebruikers toegang tot een bepaalde functie zoals verwacht?
- Welke variant ziet een bepaalde gebruiker?
Deze typen vragen kunnen worden beantwoord door middel van de emissie en analyse van evaluatie-gebeurtenissen van functievlagken. Deze bibliotheek gebruikt de System.Diagnostics.Activity
API om traceringstelemetrie te produceren tijdens de evaluatie van functievlagken.
Telemetrie inschakelen
Standaard worden er geen telemetriegegevens verzonden voor functievlagmen. Als u telemetrie voor een bepaalde functievlag wilt publiceren, moet de vlag aangeven dat deze is ingeschakeld voor telemetrie-emissie.
Voor functievlagmen die zijn gedefinieerd in appsettings.json
, wordt dit gedaan met behulp van de telemetry
eigenschap.
{
"feature_management": {
"feature_flags": [
{
"id": "MyFeatureFlag",
"enabled": true,
"telemetry": {
"enabled": true
}
}
]
}
}
Het bovenstaande codefragment voor appsettings definieert een functievlag met de naam MyFeatureFlag
die is ingeschakeld voor telemetrie. Dit wordt aangegeven door het telemetry
object dat is ingesteld op enabled
waar. De waarde van de enabled
eigenschap moet zijn true
om telemetriegegevens voor de vlag te publiceren.
De telemetry
sectie van een functievlag heeft de volgende eigenschappen:
Eigenschappen | Beschrijving |
---|---|
enabled |
Hiermee geeft u op of telemetrie moet worden gepubliceerd voor de functievlag. |
metadata |
Een verzameling sleutel-waardeparen, gemodelleerd als een woordenlijst, die kan worden gebruikt om aangepaste metagegevens over de functievlag toe te voegen aan evaluatiegebeurtenissen. |
Aangepaste telemetriepublicatie
De functiebeheerder heeft een eigen ActivitySource
naam met de naam Microsoft.FeatureManagement. Als telemetry
deze functievlag is ingeschakeld voor een functievlag, wordt er een functiebeheerder gestart Activity
wanneer de evaluatie van de functievlag wordt gestart. Wanneer de evaluatie van de functievlag is voltooid, voegt de functiebeheerder een ActivityEvent
naam FeatureFlag
toe aan de huidige activiteit. De FeatureFlag
gebeurtenis bevat tags die de informatie bevatten over de evaluatie van de functievlag, na de velden die zijn gedefinieerd in het FeatureEvaluationEvent-schema .
Notitie
Alle sleutelwaardeparen die zijn opgegeven in telemetry.metadata
de functievlag, worden ook opgenomen in de tags.
Als u aangepaste telemetriepublicaties wilt inschakelen, kunt u een ActivityListener
activiteitsbron maken en luisteren Microsoft.FeatureManagement
. Hier volgt een voorbeeld waarin wordt getoond hoe u naar de bron van de functiebeheeractiviteit luistert en een callback toevoegt wanneer een functie wordt geëvalueerd.
ActivitySource.AddActivityListener(new ActivityListener()
{
ShouldListenTo = (activitySource) => activitySource.Name == "Microsoft.FeatureManagement",
Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData,
ActivityStopped = (activity) =>
{
ActivityEvent? evaluationEvent = activity.Events.FirstOrDefault((activityEvent) => activityEvent.Name == "FeatureFlag");
if (evaluationEvent.HasValue && evaluationEvent.Value.Tags.Any())
{
// Do something.
}
}
});
Ga naar Een gedistribueerde tracering verzamelen voor meer informatie.
Application Insights Telemetry Publisher
Het Microsoft.FeatureManagement.Telemetry.ApplicationInsights
pakket biedt een ingebouwde telemetrie-uitgever waarmee evaluatiegegevens van functievlagken worden verzonden naar Application Insights. Als u hiervan gebruik wilt maken, voegt u een verwijzing naar het pakket toe en registreert u de Uitgever van Application Insights-telemetrie, zoals hieronder wordt weergegeven.
builder.services
.AddFeatureManagement()
.AddApplicationInsightsTelemetryPublisher();
Het Microsoft.FeatureManagement.Telemetry.ApplicationInsights
pakket biedt een initialisatiefunctie voor telemetrie waarmee automatisch alle gebeurtenissen TargetingId
worden gelabeld, zodat gebeurtenissen kunnen worden gekoppeld om evaluaties te markeren. Als u de initialisatiefunctie voor telemetrie wilt gebruiken, TargetingTelemetryInitializer
voegt u deze toe aan de serviceverzameling van de toepassing.
builder.Services.AddSingleton<ITelemetryInitializer, TargetingTelemetryInitializer>();
Notitie
Om ervoor te zorgen dat TargetingTelemetryInitializer
dit werkt zoals verwacht, moet de TargetingHttpContextMiddleware
hieronder beschreven versie worden gebruikt.
Als u persistentie van de doelcontext in de huidige activiteit wilt inschakelen, kunt u het TargetingHttpContextMiddleware
.
app.UseMiddleware<TargetingHttpContextMiddleware>();
Een voorbeeld van het gebruik ervan vindt u in het voorbeeld VariantAndTelemetryDemo .
Vereiste
Deze telemetrie-uitgever is afhankelijk van de installatie van Application Insights die al is geregistreerd als een toepassingsservice. Dit wordt bijvoorbeeld gedaan in de voorbeeldtoepassing.
Deze telemetrie-uitgever is afhankelijk van dat Application Insights al wordt ingesteld en geregistreerd als een toepassingsservice.
Caching
De functiestatus wordt geleverd door het IConfiguration
systeem. Alle caching en dynamische updates worden naar verwachting verwerkt door configuratieproviders. De functiebeheerder vraagt om IConfiguration
de meest recente waarde van de status van een functie wanneer een functie wordt ingeschakeld.
Momentopname
Er zijn scenario's waarbij de status van een functie consistent moet blijven tijdens de levensduur van een aanvraag. De waarden die worden geretourneerd op basis van de standaard IFeatureManager
, kunnen veranderen als de IConfiguration
bron waaruit deze wordt opgehaald, tijdens de aanvraag wordt bijgewerkt. Dit kan worden voorkomen door gebruik te maken van IFeatureManagerSnapshot
. IFeatureManagerSnapshot
kan op dezelfde manier worden opgehaald als IFeatureManager
. IFeatureManagerSnapshot
implementeert de interface van IFeatureManager
, maar slaat de eerste geëvalueerde status van een functie tijdens een aanvraag in de cache op en retourneert dezelfde status van een functie tijdens de levensduur.
Aangepaste functieproviders
Door een aangepaste functieprovider te implementeren, kunnen ontwikkelaars functievlagmen ophalen uit bronnen zoals een database of een functiebeheerservice. De meegeleverde functieprovider die standaard wordt gebruikt, haalt functievlagmen op uit het configuratiesysteem van .NET Core. Hierdoor kunnen functies worden gedefinieerd in een appsettings.json-bestand of in configuratieproviders zoals Azure-app Configuratie. Dit gedrag kan worden vervangen door volledige controle over waar functiedefinities vandaan worden gelezen.
Als u het laden van functiedefinities wilt aanpassen, moet u de IFeatureDefinitionProvider
interface implementeren.
public interface IFeatureDefinitionProvider
{
Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName);
IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}
Als u een implementatie van IFeatureDefinitionProvider
wilt gebruiken, moet deze worden toegevoegd aan de serviceverzameling voordat u functiebeheer toevoegt. In het volgende voorbeeld wordt een implementatie van IFeatureDefinitionProvider
de naam InMemoryFeatureDefinitionProvider
toegevoegd.
services.AddSingleton<IFeatureDefinitionProvider, InMemoryFeatureDefinitionProvider>()
.AddFeatureManagement()
Volgende stappen
Als u wilt weten hoe u functievlagmen in uw toepassingen gebruikt, gaat u verder met de volgende quickstarts.
Als u wilt weten hoe u functiefilters gebruikt, gaat u verder met de volgende zelfstudies.
Ga verder met de volgende zelfstudie voor meer informatie over het uitvoeren van experimenten met variantfunctievlagmen.