练习 - 实现功能标记以控制 ASP.NET Core 应用功能

已完成

在本练习中实现一个功能标记,为应用程序切换季节性销售横幅。 使用功能标记,无需重新部署应用即可切换功能可用性。

你将在 .NET 功能标志库中使用功能管理。 此库提供了在应用中实现功能标志的帮助程序。 该库支持将条件语句等简单用例用于更高级的方案,例如,有条件地添加路由或操作筛选器。 此外,它还支持功能筛选器,使你能够基于特定参数启用功能。 此类参数的示例包括窗口时间、百分比或用户子集。

在本单元中,你将学习以下内容:

  • 创建 Azure 应用配置实例。
  • 向应用程序配置存储添加功能标志。
  • 将你的应用连接到应用配置存储。
  • 修改应用程序以使用功能标记。
  • 更改产品页以显示销售横幅。
  • 生成并测试应用。

打开开发环境

可以选择使用托管练习的 GitHub codespace,或者在 Visual Studio Code 中本地完成练习。

若要使用 codespace,请使用此 Codespace 创建链接创建预配置的 GitHub Codespace

GitHub 需要几分钟时间来创建和配置 codespace。 完成后,你会看到此练习的代码文件。 用于本模块其余部分的代码位于 /dotnet-feature-flags 目录中

若要使用 Visual Studio Code,请将 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative 存储库克隆到本地计算机。 然后:

  1. 安装任何系统要求以在 Visual Studio Code 中运行开发容器。
  2. 确保 Docker 正在运行。
  3. 在新的 Visual Studio Code 窗口中,打开克隆存储库的文件夹
  4. Ctrl+Shift+P,以打开命令面板。
  5. 搜索:>开发容器:在容器中重新生成和重新打开
  6. 从下拉列表中选择“eShopLite - dotnet-feature-flags”。 Visual Studio Code 会在本地创建开发容器。

创建应用程序配置实例

完成以下步骤,在 Azure 订阅中创建一个应用程序配置实例:

  1. 在“新建终端”窗格中,登录到 Azure CLI。

    az login --use-device-code
    
  2. 查看选择的 Azure 订阅。

    az account show -o table
    

    如果选择了错误的订阅,请使用 az account set 命令选择正确的订阅。

  3. 运行以下 Azure CLI 命令,获取 Azure 区域及其关联名称的列表:

    az account list-locations -o table
    

    找到离你最近的区域,并在下一步中使用它替换 [Closest Azure region]

  4. 运行以下 Azure CLI 命令来创建应用配置实例:

    export LOCATION=[Closest Azure region]
    export RESOURCE_GROUP=rg-eshop
    export CONFIG_NAME=eshop-app-features$SRANDOM    
    

    需要将 LOCATION 更改为一个靠近你的 Azure 区域,例如 eastus。 如果想为资源组或应用配置使用其他名称,请更改上面的值。

  5. 运行以下命令创建 Azure 资源组:

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  6. 运行以下命令以创建应用配置实例:

    az appconfig create --resource-group $RESOURCE_GROUP --name $CONFIG_NAME --location $LOCATION --sku Free
    

    随即显示以下输出的变体:

    {
      "createMode": null,
      "creationDate": "2023-10-31T15:40:10+00:00",
      "disableLocalAuth": false,
      "enablePurgeProtection": false,
      "encryption": {
        "keyVaultProperties": null
      },
      "endpoint": "https://eshop-app-features1168054702.azconfig.io",
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/rg-eshop/providers/Microsoft.AppConfiguration/configurationStores/eshop-app-features1168054702",
      "identity": null,
    
  7. 运行以下命令,检索应用配置实例的连接字符串:

    az appconfig credential list --resource-group $RESOURCE_GROUP --name $CONFIG_NAME --query [0].connectionString --output tsv
    

    Endpoint= 为前缀的这个字符串表示应用配置存储的连接字符串。

  8. 复制该连接字符串。 你稍后将使用它。

存储应用程序配置连接字符串

现在,你要将应用配置连接字符串添加到应用程序。 请完成下列步骤:

  1. 打开 /dotnet-feature-flags/docker-compose.yml 文件。

  2. 在第 13 行添加新环境变量。

    - ConnectionStrings:AppConfig=[PASTE CONNECTION STRING HERE]
    

    docker-compose.yml 将类似于以下 YAML:

    environment: 
      - ProductEndpoint=http://backend:8080
      - ConnectionStrings:AppConfig=Endpoint=https://eshop-app-features1168054702.azconfig.io;Id=<ID>;Secret=<Secret value>
    

上一行表示一个键值对,其中 ConnectionStrings:AppConfig 是环境变量名称。 在 Store 项目中,环境变量配置提供程序将读取其值。

提示

你的 Azure 应用程序配置连接字符串包含纯文本密码。 在实际应用中,考虑将应用程序配置与 Azure Key Vault 集成,以确保机密的安全存储。 Key Vault 不在此模块的范围内,但可以在教程:在 ASP.NET Core 应用中使用 Key Vault 引用中找到相关指南。

向应用程序配置存储添加功能标志

在 Azure 应用程序配置中,创建并启用要视为功能标志的键值对。 完成以下步骤:

  1. 在另一个浏览器选项卡中,使用与 Azure CLI 相同的帐户和目录登录到 Azure 门户

  2. 使用搜索框查找并打开以 eshop-app-features 为前缀的应用程序配置资源。

    Azure 门户搜索结果的屏幕截图,其中显示前缀为“eshop-app-features”的应用配置资源。

  3. 在“操作”部分中,选择“功能管理器”。

  4. 在顶部菜单中,选择“+ 创建”

  5. 选中“启用功能标记”复选框。

  6. “功能标记名称”文本框中,输入 SeasonalDiscount

  7. 选择“应用”。

    新增功能标志的屏幕截图。

    现在功能标志存在于应用程序配置存储中,Store 项目需要进行一些更改才能进行读取。

查看代码

查看 IDE 的“资源管理器”窗格中的目录。 请注意,有三个项目:DataEntitiesProductsStoreStore 项目是 Blazor 应用。 Products 项目是包含产品服务的 .NET Standard 库。 DataEntities 项目是包含产品模型的 .NET Standard 库。

将你的应用连接到应用程序配置存储

若要从 ASP.NET Core 应用中的应用程序配置存储访问值,需要应用程序配置的配置提供程序。

Store 项目应用以下更改:

  1. 在终端窗口中,导航到 Store 文件夹:

    cd dotnet-feature-flags/Store
    
  2. 运行以下命令以安装 NuGet 包,其中包含适用于应用程序配置服务的 .NET 配置提供程序:

    dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore
    dotnet add package Microsoft.FeatureManagement.AspNetCore
    dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
    
  3. 打开 Store/Program.cs 文件。

  4. 在文件顶部添加新包引用:

    using Microsoft.FeatureManagement;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
  5. 将此代码添加到 // Add the AddAzureAppConfiguration code 注释下方。

    // Retrieve the connection string
    var connectionString = builder.Configuration.GetConnectionString("AppConfig");
    
    // Load configuration from Azure App Configuration
    builder.Configuration.AddAzureAppConfiguration(options => {
      options.Connect(connectionString)
        .UseFeatureFlags();
    });
    
    // Register the Feature Management library's services
    builder.Services.AddFeatureManagement();
    builder.Services.AddAzureAppConfiguration();
    

    在前面的代码片段中:

    • Connect 方法对应用程序配置存储进行身份验证。 回想一下,连接字符串作为环境变量 ConnectionStrings:AppConfig 传递。
    • UseFeatureFlags 方法使功能管理库能够从应用配置存储中读取功能标记。
    • 两个 builder.Services 调用向应用的依赖项注入容器注册功能管理库的服务。
  6. 在文件底部的 // Add the App Configuration middleware 下方,添加以下代码:

    app.UseAzureAppConfiguration();
    

    前面的代码将应用程序配置中间件添加到请求管道。 中间件针对每个传入请求触发功能管理参数的刷新操作。 然后,由 AzureAppConfiguration 提供程序根据刷新设置来决定何时实际连接到存储以获取值。

启用销售横幅

应用现在可以读取功能标记,但产品页面需要更新才能显示促销正在进行。 请完成下列步骤:

  1. 打开 Store/Components/Pages/Products.razor 文件。

  2. 在该文件的顶部,添加以下代码:

    @using Microsoft.FeatureManagement
    @inject IFeatureManager FeatureManager
    

    前面的代码导入功能管理库的命名空间并将 IFeatureManager 接口注入到组件中。

  3. @code 节中,添加以下变量来存储功能标记的状态:

    private bool saleOn = false;  
    
  4. OnInitializedAsync 方法中,添加以下代码:

    saleOn = await FeatureManager.IsEnabledAsync("SeasonalDiscount");
    

    该方法应如以下代码所示:

    protected override async Task OnInitializedAsync()
    {
        saleOn = await FeatureManager.IsEnabledAsync("SeasonalDiscount");
    
        // Simulate asynchronous loading to demonstrate streaming rendering
        products = await ProductService.GetProducts();
    }
    
  5. 在第 26 行的 <!-- Add a sales alert for customers --> 注释下,添加以下代码:

    <!-- Add a sales alert for customers -->
    @if (saleOn)
    {
    <div class="alert alert-success" role="alert">
      Our sale is now on.
    </div>
    }
    

    如果启用了功能标记,前面的代码将显示销售警报。

生成应用

  1. 确保已保存所有更改,并且位于 dotnet-feature-flags 目录中。 在终端中运行以下命令:

    dotnet publish /p:PublishProfile=DefaultContainer 
    
  2. 使用 docker 运行应用:

    docker compose up
    

测试功能标志

若要验证功能标记是否在 codespace 中正常工作,请完成以下步骤:

  1. 切换到“端口”选项卡,然后在“前端”端口的本地地址右侧,选择地球图标。 浏览器将在主页上打开一个新选项卡。
  2. 选择“产品”。

如果你在本地使用 Visual Studio Code,请打开 http://localhost:32000/products

显示产品页上销售警报的屏幕截图。

在 Azure 门户中,可以启用和禁用功能标志并刷新产品页以查看标志的效果。