Share via


.NET-functiebeheer

Microsoft.FeatureManagement
Microsoft.FeatureManagement.AspNetCore

Microsoft.FeatureManagement
Microsoft.FeatureManagement.AspNetCore
Microsoft.FeatureManagement.Telemetry.ApplicationInsights

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
  • 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 AlwaysOnwe . 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 Anyde 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 Anyde 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 IFeatureManagerIsEnabledAsync 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 SomeMvcFiltertoegevoegd. 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 MyCriteriaFiltertoevoegt.

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 IAccountContextgeï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 ContextTypeis.

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 is TypeC, 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, TimeWindowFilteren TargetingFilterContextualTargetingFilter . Alle filters, met uitzondering van de TargetingFilterfilters, 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: NoEnden 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:

  1. Individuele gebruikers Jeff en Alicia krijgen toegang tot de bètaversie
  2. Een andere gebruiker, Mark, vraagt zich aan te aanmelden en is inbegrepen.
  3. Twintig procent van een groep die bekend staat als Ring1-gebruikers, worden opgenomen in de bètaversie.
  4. Het aantal ring1-gebruikers dat in de bètaversie is opgenomen, wordt tot 100 procent opgestoten.
  5. Vijf procent van de gebruikersbasis is opgenomen in de bètaversie.
  6. 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 ExampleTargetingContextAccessorimplementatieITargetingContextAccessor.

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 Markheeft, 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 IVariantFeatureManagermethode.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 useren grouppercentile toewijzingen om een variant toe te wijzen. Als in dit specifieke voorbeeld de gebruiker die wordt geëvalueerd de naam Marshaheeft, in de groep met de naam Ring1of 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 VariantServiceAliasAttributeservice, 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 Activitywanneer 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, TargetingTelemetryInitializervoegt 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 IFeatureDefinitionProviderwilt gebruiken, moet deze worden toegevoegd aan de serviceverzameling voordat u functiebeheer toevoegt. In het volgende voorbeeld wordt een implementatie van IFeatureDefinitionProvider de naam InMemoryFeatureDefinitionProvidertoegevoegd.

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.