使用 .NET Aspire 清单自定义连接字符串

已完成

部署工具(如 Visual Studio 或 Azure Developer CLI)可创建描述 .NET Aspire 解决方案内容的清单文件。 如果要自定义部署,可以直接更改清单文件。

在你的户外设备零售商中,你决定使用现有的 Azure Cache for Redis 实例来托管 Web 应用微服务的输出缓存。 你需要确保 Web 应用服务连接到正确的 Azure Cache for Redis 实例。

在本单元中,你将了解如何更改连接字符串更改为 .NET Aspire 清单文件中的后端服务。

使用 .NET CLI 生成清单文件

在本地开发和调试期间,.NET Aspire 不会创建清单文件。 在部署方面,.NET 必须描述 .NET Aspire 解决方案的内容,包括其微服务、后端服务和配置。 清单文件就是为此目的服务的。 它以 JSON 格式描述解决方案。

为了创建清单文件,Visual Studio 和 Azure Developer CLI 都会运行具有特定目标的 .NET CLI run 命令。 可以手动运行相同的命令来创建自己的清单文件,如下所示:

dotnet run --project eShop.AppHost\eShop.AppHost.csproj `
    --publisher manifest `
    --output-path ../aspire-manifest.json

注意

请确保使用 --project 选项指定应用主机项目。

该命令生成类似于以下文本的输出:

Building...
info: Aspire.Hosting.DistributedApplication[0]
      Aspire version: 8.0.1+a6e341ebbf956bbcec0dda304109815fcbae70c9
info: Aspire.Hosting.Publishing.ManifestPublisher[0]
      Published manifest to: C:\repos\eShop\aspire-manifest.json

还可以使用启动配置文件来运行 dotnet 命令。 启动配置文件是一组设置,可在运行时配置 .NET 项目。 例如,.NET Aspire 初学者模板可创建以下启动配置文件:

"profiles": {
  "https": {
    "commandName": "Project",
    "dotnetRunMessages": true,
    "launchBrowser": true,
    "applicationUrl": "https://localhost:17170;http://localhost:15281",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development",
      "DOTNET_ENVIRONMENT": "Development",
      "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21147",
      "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22239"
    }
  },
  "http": {
    "commandName": "Project",
    "dotnetRunMessages": true,
    "launchBrowser": true,
    "applicationUrl": "http://localhost:15281",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development",
      "DOTNET_ENVIRONMENT": "Development",
      "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19197",
      "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20233"
    }
  }
}

添加启动配置文件,以创建包含类似于以下文本的 JSON 代码的清单文件:

"profiles": {
  "generate-manifest": {
    "commandName": "Project",
    "launchBrowser": false,
    "dotnetRunMessages": true,
    "commandLineArgs": "--publisher manifest --output-path aspire-manifest.json"
  }
}

然后,在 Visual Studio 中,可以在开始调试时选择“generate-manifest”配置文件。 在命令行中,使用 --launch-profile 选项:

dotnet run --launch-profile generate-manifest

清单文件的格式

清单是一个 JSON 文件,其中包含一个名为 resources 的顶级元素。 在该对象中,可以找到每个微服务和后端服务的一个对象。 对于每个此类对象,设置包括连接字符串、环境变量和容器映像名称。

下面是未经修改的 .NET Aspire 初学者模板的示例清单。 该解决方案使用了 Redis 缓存:

{
  "resources": {
    "cache": {
      "type": "container.v0",
      "connectionString": "{cache.bindings.tcp.host}:{cache.bindings.tcp.port}",
      "image": "docker.io/library/redis:7.2",
      "bindings": {
        "tcp": {
          "scheme": "tcp",
          "protocol": "tcp",
          "transport": "tcp",
          "targetPort": 6379
        }
      }
    },
    "apiservice": {
      "type": "project.v0",
      "path": "AspireStarter.ApiService/AspireStarter.ApiService.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true"
      },
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http"
        },
        "https": {
          "scheme": "https",
          "protocol": "tcp",
          "transport": "http"
        }
      }
    },
    "webfrontend": {
      "type": "project.v0",
      "path": "AspireStarter.Web/AspireStarter.Web.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true",
        "ConnectionStrings__cache": "{cache.connectionString}",
        "services__apiservice__http__0": "{apiservice.bindings.http.url}",
        "services__apiservice__https__0": "{apiservice.bindings.https.url}"
      },
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http",
          "external": true
        },
        "https": {
          "scheme": "https",
          "protocol": "tcp",
          "transport": "http",
          "external": true
        }
      }
    }
  }
}

连接字符串和绑定引用

该清单示例中包括三个资源:

  • webfrontend:此资源是向客户显示 Web 界面的微服务。
  • apiservice:此资源是 webfrontend 调用的 REST API。 在模板中,此调用的目的是获取天气数据。
  • cache:此资源是 Redis 缓存,用于优化 webfrontend 微服务的性能。

请注意,这三个资源中的每一个都包含一个 bindings 部分,用于指定可用于连接到该资源的协议。

在应用主机的 Program.cs 文件中,webfrontend 项目取决于 cacheapiservice 两者:

var cache = builder.AddRedis("cache");

var apiService = builder.AddProject<Projects.AspireStarter_ApiService>("apiservice");

builder.AddProject<Projects.AspireStarter_Web>("webfrontend")
    .WithExternalHttpEndpoints()
    .WithReference(cache)
    .WithReference(apiService);

在清单文件中,以下依赖项会表示为环境变量:

"env": {
  "ConnectionStrings__cache": "{cache.connectionString}",
  "services__apiservice__http__0": "{apiservice.bindings.http.url}",
  "services__apiservice__https__0": "{apiservice.bindings.https.url}"
}

关系图显示了 .NET Aspire 项目中的依赖项如何生成清单文件中的引用。

依赖项使用引用清单文件结构的占位符字符串。 例如,第三个依赖项引用了 API 服务 HTTPS 绑定:

关系图显示了如何在 .NET Aspire 清单文件中构造占位符。

了解详细信息