Tutorial: Verwenden von Featureflags in einer ASP.NET Core-App

Die .NET-Featureverwaltungsbibliotheken bieten idiomatische Unterstützung für die Implementierung von Featureflags in einer .NET- oder ASP.NET Core-Anwendung. Dank dieser Bibliotheken können Sie Ihrem Code auf deklarative Weise Featureflags hinzufügen und sich das manuelle Schreiben von Code zum Aktivieren oder Deaktivieren von Features mit Anweisungen vom Typ if sparen.

Die Featureverwaltungsbibliotheken verwalten darüber hinaus Featureflag-Lebenszyklen im Hintergrund. Die Bibliotheken können Flagzustände aktualisieren und zwischenspeichern, garantieren, dass ein Flagzustand während eines Anforderungsaufrufs unveränderlich ist, und Ähnliches. Darüber hinaus bietet die ASP.NET Core-Bibliothek sofort einsetzbare Integrationen – einschließlich MVC-Controlleraktionen, Ansichten, Routen und Middleware.

Die Referenzdokumentation zur Featureverwaltungs-API von ASP.NET Core finden Sie unter Namespace „Microsoft.FeatureManagement“.

In diesem Tutorial lernen Sie Folgendes:

  • Hinzufügen von Featureflags in wichtigen Teilen Ihrer Anwendung, um die Verfügbarkeit von Features zu steuern
  • Integrieren in App Configuration, wenn Sie damit Featureflags verwalten

Voraussetzungen

Unter Schnellstart: Hinzufügen von Featureflags zu einer ASP.NET Core-App finden Sie ein einfaches Beispiel für die Verwendung von Featureflags in einer ASP.NET Core-Anwendung. In diesem Tutorial werden weitere Einrichtungsoptionen und Funktionen der Featureverwaltungsbibliotheken gezeigt. Sie können die in der Schnellstartanleitung erstellte Beispiel-App verwenden, um den in diesem Tutorial gezeigten Beispielcode zu testen.

Einrichten der Featureverwaltung

Um auf den .NET-Feature-Manager zuzugreifen, muss Ihre App Verweise auf die Microsoft.Azure.AppConfiguration.AspNetCore und Microsoft.FeatureManagement.AspNetCore NuGet-Pakete haben.

Der .NET-Feature-Manager wird über das native Konfigurationssystem des Frameworks konfiguriert. Dadurch können Sie die Featureflageinstellungen Ihrer Anwendung mit einer beliebigen, von .NET unterstützten Konfigurationsquelle konfigurieren – unter anderem mit der lokalen Datei appsettings.json oder mit Umgebungsvariablen.

Der Feature-Manager ruft die Featureflagkonfiguration standardmäßig aus dem Abschnitt "FeatureManagement" der .NET-Konfigurationsdaten ab. Wenn Sie den Standardspeicherort für die Konfiguration verwenden möchten, können Sie die Methode AddFeatureManagement der Sammlung IServiceCollection aufrufen, die an die Methode ConfigureServices der Klasse Startup übergeben wurde.

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement();

Soll die Featureverwaltungskonfiguration aus einem anderen Konfigurationsabschnitt abgerufen werden, rufen Sie Configuration.GetSection auf, und übergeben Sie den Namen des gewünschten Abschnitts. Im folgenden Beispiel wird er angewiesen, sie stattdessen aus einem Abschnitt namens "MyFeatureFlags" zu lesen:

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement(Configuration.GetSection("MyFeatureFlags"));

Wenn Sie in Ihren Featureflags Filter verwenden, müssen Sie den Namespace Microsoft.FeatureManagement.FeatureFilters einschließen und einen Aufruf von AddFeatureFilter hinzufügen und den Typnamen des Filters, den Sie verwenden wollen, als generischen Typ der Methode angeben. Weitere Informationen zur Verwendung von Featurefiltern zum dynamischen Aktivieren und Deaktivieren von Funktionen finden Sie unter Aktivieren des gestaffelten Rollouts von Features für Zielgruppen.

Das folgende Beispiel zeigt, wie Sie einen integrierten Featurefilter namens PercentageFilter verwenden:

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement()
    .AddFeatureFilter<PercentageFilter>();

Featureflags sollten sich außerhalb der Anwendung befinden und separat verwaltet werden, anstatt sie in Ihrer Anwendung hart zu codieren. Dadurch können Sie Flagzustände jederzeit ändern, und die Änderungen werden in der Anwendung sofort wirksam. Der Azure App Configuration-Dienst bietet eine dedizierte Portalbenutzeroberfläche, über die Sie alle Ihre Featureflags verwalten können. Darüber hinaus übermittelt der Azure App Configuration-Dienst die Featureflags unter Verwendung der zugehörigen .NET-Clientbibliotheken direkt an Ihre Anwendung.

Die Verbindung zwischen Ihrer ASP.NET Core-Anwendung und App Configuration lässt sich am einfachsten über den im NuGet-Paket Microsoft.Azure.AppConfiguration.AspNetCore enthaltenen Konfigurationsanbieter herstellen. Nachdem Sie einen Verweis auf das Paket eingeschlossen haben, können Sie dieses NuGet-Paket wie folgt verwenden:

  1. Öffnen Sie die Datei Program.cs, und fügen Sie folgenden Code hinzu.

    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Configuration.AddAzureAppConfiguration(options =>
        options.Connect(
            builder.Configuration["ConnectionStrings:AppConfig"])
            .UseFeatureFlags());
    
  2. Aktualisieren Sie die Middleware- und Dienstkonfigurationen für Ihre App mithilfe des folgenden Codes.

    Registrieren Sie in der program.cs-Klasse die Azure App Configuration-Dienste und Middleware für die builder- und app-Objekte:

    builder.Services.AddAzureAppConfiguration();
    
    app.UseAzureAppConfiguration();
    

In einem typischen Szenario aktualisieren Sie die Featureflagwerte regelmäßig, um verschiedene Features Ihrer Anwendung bereitzustellen und zu aktivieren. Standardmäßig werden die Featureflagwerte für einen Zeitraum von 30 Sekunden zwischengespeichert, daher würde ein Aktualisierungsvorgang, der ausgelöst wird, wenn die Middleware eine Anforderung empfängt, den Wert erst nach Ablauf des zwischengespeicherten Werts aktualisieren. Der folgende Code zeigt, wie Sie die Cacheablaufzeit oder das Abrufintervall unter Verwendung von CacheExpirationInterval im Aufruf von UseFeatureFlags auf fünf Minuten festlegen.

config.AddAzureAppConfiguration(options =>
    options.Connect(
        builder.Configuration["ConnectionStrings:AppConfig"])
            .UseFeatureFlags(featureFlagOptions => {
                featureFlagOptions.CacheExpirationInterval = TimeSpan.FromMinutes(5);
    }));

Featureflagdeklaration

Jede Featureflagdeklaration besteht aus zwei Teilen: einem Namen und einer Filterliste, anhand der ausgewertet wird, ob ein Feature aktiviert ist (der Wert also True lautet). Ein Filter definiert ein Kriterium für die Aktivierung eines Features.

Verfügt ein Featureflag über mehrere Filter, wird die Filterliste in der angegebenen Reihenfolge durchlaufen, bis einer der Filter angibt, dass das Feature aktiviert werden soll. Daraufhin ist das Featureflag aktiviert, und alle weiteren Filterergebnisse werden übersprungen. Falls durch keinen Filter angegeben wird, dass das Feature aktiviert werden soll, ist das Featureflag deaktiviert.

Der Feature-Manager unterstützt appsettings.json als Konfigurationsquelle für Featureflags. Das folgende Beispiel zeigt die Einrichtung von Featureflags in einer JSON-Datei:

{"FeatureManagement": {
        "FeatureA": true, // Feature flag set to on
        "FeatureB": false, // Feature flag set to off
        "FeatureC": {
            "EnabledFor": [
                {
                    "Name": "Percentage",
                    "Parameters": {
                        "Value": 50
                    }
                }
            ]
        }
    }
}

Der Abschnitt FeatureManagement dieses JSON-Dokuments wird konventionsgemäß für Featureflageinstellungen verwendet. Das vorherige Beispiel enthält drei Featureflags, deren Filter in der Eigenschaft EnabledFor definiert sind:

  • FeatureA ist aktiviert.
  • FeatureB ist deaktiviert.
  • FeatureC gibt einen Filter namens Percentage mit einer Eigenschaft vom Typ Parameters an. Percentage ist ein konfigurierbarer Filter. In diesem Beispiel gibt Percentage an, dass das Flag FeatureC mit einer Wahrscheinlichkeit von 50 Prozent aktiviert ist. Eine Anleitung zur Verwendung von Featurefiltern finden Sie unter Verwenden von Featurefiltern, um bedingte Featureflags zu aktivieren.

Verwenden von Abhängigkeitsinjektion für den Zugriff auf „IFeatureManager“

Bei einigen Vorgängen (etwa beim manuellen Überprüfen von Featureflagwerten) muss eine Instanz von IFeatureManager abgerufen werden. In ASP.NET Core MVC kann auf den Feature-Manager IFeatureManager mittels Abhängigkeitsinjektion zugegriffen werden. Im folgenden Beispiel wird der Signatur des Konstruktors für einen Controller ein Argument vom Typ IFeatureManager hinzugefügt. Die Runtime löst den Verweis automatisch auf und stellt beim Aufrufen des Konstruktors eine Implementierung der Schnittstelle bereit. Wenn Sie eine Anwendungsvorlage verwenden, in der für den Controller bereits mindestens ein Abhängigkeitsinjektionsargument im Konstruktor (beispielsweise ILogger) vorhanden ist, können Sie einfach IFeatureManager als zusätzliches Argument hinzufügen:

using Microsoft.FeatureManagement;

public class HomeController : Controller
{
    private readonly IFeatureManager _featureManager;

    public HomeController(ILogger<HomeController> logger, IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

Featureflag-Verweise

Definieren Sie Featureflags als Zeichenfolgenvariablen, um im Code auf sie verweisen zu können:

public static class MyFeatureFlags
{
    public const string FeatureA = "FeatureA";
    public const string FeatureB = "FeatureB";
    public const string FeatureC = "FeatureC";
}

Überprüfen von Featureflags

Bei der Featureverwaltung wird häufig folgendes Muster verwendet: Es wird überprüft, ob ein Featureflag aktiviert ist, und ein Codeabschnitt ausgeführt, wenn dies der Fall ist. Beispiel:

IFeatureManager featureManager;
...
if (await featureManager.IsEnabledAsync(MyFeatureFlags.FeatureA))
{
    // Run the following code
}

Controlleraktionen

Bei Verwendung von MVC-Controllern können Sie mithilfe des Attributs FeatureGate steuern, ob eine gesamte Controllerklasse oder eine spezifische Aktion aktiviert werden soll. Für den folgenden Controller HomeController muss FeatureAaktiviert sein, damit eine der in der Controllerklasse enthaltenen Aktionen ausgeführt werden kann:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public class HomeController : Controller
{
    ...
}

Für die folgende Aktion Index muss FeatureAaktiviert sein, damit sie ausgeführt werden kann:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public IActionResult Index()
{
    return View();
}

Ist ein MVC-Controller oder eine Aktion blockiert, da das steuernde Featureflag deaktiviert ist, wird eine registrierte Schnittstelle vom Typ IDisabledFeaturesHandler aufgerufen. Die Standardschnittstelle IDisabledFeaturesHandler gibt den Statuscode 404 ohne Antworttext an den Client zurück.

MVC-Ansichten

Öffnen Sie _ViewImports.cshtml im Verzeichnis Views, und fügen Sie das Taghilfsprogramm für den Feature-Manager hinzu:

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

In MVC-Ansichten können Sie ein Tag vom Typ <feature> verwenden, um das Rendern von Inhalten vom Aktivierungsstatus eines Featureflags abhängig zu machen:

<feature name="FeatureA">
    <p>This can only be seen if 'FeatureA' is enabled.</p>
</feature>

Um alternative Inhalte anzuzeigen, wenn die Anforderungen nicht erfüllt sind, kann das negate-Attribut verwendet werden.

<feature name="FeatureA" negate="true">
    <p>This will be shown if 'FeatureA' is disabled.</p>
</feature>

Das <feature>-Tag kann auch verwendet werden, um Inhalte anzuzeigen, wenn ein oder alle Features in einer Liste aktiviert sind.

<feature name="FeatureA, FeatureB" requirement="All">
    <p>This can only be seen if 'FeatureA' and 'FeatureB' are enabled.</p>
</feature>
<feature name="FeatureA, FeatureB" requirement="Any">
    <p>This can be seen if 'FeatureA', 'FeatureB', or both are enabled.</p>
</feature>

MVC-Filter

Sie können MVC-Filter so einrichten, dass sie abhängig vom Zustand eines Featureflags aktiviert werden. Diese Funktion ist auf Filter beschränkt, von denen IAsyncActionFilter implementiert wird. Im folgenden Code wird ein MVC-Filter namens ThirdPartyActionFilter hinzugefügt. Dieser Filter wird innerhalb der MVC-Pipeline nur ausgelöst, wenn FeatureA aktiviert ist.

using Microsoft.FeatureManagement.FeatureFilters;

IConfiguration Configuration { get; set;}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => {
        options.Filters.AddForFeature<ThirdPartyActionFilter>(MyFeatureFlags.FeatureA);
    });
}

Middleware

Featureflags ermöglichen außerdem das bedingte Hinzufügen von Anwendungsbranches und Middleware. Im folgenden Code wird nur dann eine Middlewarekomponente in die Anforderungspipeline eingefügt, wenn FeatureA aktiviert ist:

app.UseMiddlewareForFeature<ThirdPartyMiddleware>(MyFeatureFlags.FeatureA);

Dieser Code baut auf der allgemeineren Verzweigung der gesamten Anwendung auf der Grundlage eines Featureflags auf:

app.UseForFeature(featureName, appBuilder => {
    appBuilder.UseMiddleware<T>();
});

Nächste Schritte

In diesem Tutorial haben Sie gelernt, wie Sie Featureflags in Ihrer ASP.NET Core-Anwendung unter Verwendung der Bibliotheken vom Typ Microsoft.FeatureManagement implementieren. Die folgenden Ressourcen enthalten weitere Informationen zur Unterstützung der Featureverwaltung in ASP.NET Core und App Configuration: