冠军

导航

.NET Aspire 外部参数 (External parameters)

.NET Aspire 外部参数 (External parameters)

https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/external-parameters

环境提供应用运行的上下文。Parameter 提供了在应用运行中请求外部值的功能。当应用本地运行的时候,Parameter 可以为应用提供值,或者在应用部署的时候,提示值。Parameter 可以用于建模各种场景,包括密钥,连接串,以及其它在各种环境下变得不同的配置值。

参数值

参数的值可以通过 app host 的配置读取,然后用于本地运行的应用。当部署应用的时候,实际的值会通过参数值来获得。

考虑下面的 app host 的 Program.cs 示例。

var builder = DistributedApplication.CreateBuilder(args);

// Add a parameter
IResourceBuilder<ParameterResource> value = builder.AddParameter("value");

builder.AddProject<Projects.ApiService>("api")
       .WithEnvironment("EXAMPLE_VALUE", value);

相应的 appsettings.json 为:

{
    "Parameters": {
        "value": "local-value"
    }
}

参数在清单中表示为名为 parameter.v0 的新基元:

{
  "resources": {
    "value": {
      "type": "parameter.v0",
      "value": "{value.inputs.value}",
      "inputs": {
        "value": {
          "type": "string"
        }
      }
    }
  }
}

密钥

参数 Parameter 还可以用来建模密钥。当一个 Parameter 标记为密钥的时候,它提示清单该值应该被看做密钥。在部署中需要提示并保存在安全的位置。

当在本地运行的时候,该值将通过 app host 的配置中的 Parameters 配置节中读取出来。

考虑下面的 app host 中的 Program.cs 代码示例:

var builder = DistributedApplication.CreateBuilder(args);

// Add a secret parameter
var secret = builder.AddParameter("secret", secret: true);

builder.AddProject<Projects.ApiService>("api")
       .WithEnvironment("SECRET", secret);

builder.Build().Run();

现在考虑相应的 app host 中如下的 appsettings.josn

{
    "Parameters": {
        "secret": "local-secret"
    }
}

清单文件中的表示如下:

{
  "resources": {
    "value": {
      "type": "parameter.v0",
      "value": "{value.inputs.value}",
      "inputs": {
        "value": {
          "type": "string",
          "secret": true
        }
      }
    }
  }
}

连接串的值

Parameter 还可以用来建模连接串。在部署中,该值将被提示并保存到安全的位置。

当本地运行的时候,该值将通过 app host 的配置中的 ConnectionString 配置节中读取出来。

注意

连接串用来表示广义的连接信息,包括数据库连接串,消息中间件,以及其它服务。

在 .NET Aspire 的命名方式中,术语 connection string 用来表示任意类型的连接信息。

考虑如下的 app host 的 Program.cs 示例

var builder = DistributedApplication.CreateBuilder(args);

var redis = builder.AddConnectionString("redis");

builder.AddProject<Projects.WebApplication1>("api")
       .WithReference(redis);

builder.Build().Run();

相应的 app host 的 appsettings.json 如下所示

{
    "ConnectionStrings": {
        "redis": "local-connection-string"
    }
}

清单表示如下所示

{
  "resources": {
    "redis": {
      "type": "parameter.v0",
      "connectionString": "{redis.value}",
      "value": "{redis.inputs.value}",
      "inputs": {
        "value": {
          "type": "string",
          "secret": true
        }
      }
    }
  }
}

Parameter 示例

为了表示 Parameter,考虑如下的示例代码:

var builder = DistributedApplication.CreateBuilder(args);

var db = builder.AddSqlServer("sql")
                .PublishAsConnectionString()
                .AddDatabase("db");

var insertionRows = builder.AddParameter("insertionRows");

builder.AddProject<Projects.Parameters_ApiService>("api")
       .WithEnvironment("InsertionRows", insertionRows)
       .WithReference(db);

builder.Build().Run();

实际执行如下步骤:

  • 添加了名为 sql 的 SQL Server 资源,并发布为数据库连接串
  • 添加了名为 db 的数据库
  • 添加了名为 insertionRows 的 Parameter
  • 添加了名为 api 的项目,将其关联到项目 Projects.Parameters_ApiService 项目资源类型参数上
  • 将参数 insertionRows 传递给 api 项目
  • 引用 db 数据库

其中的 insertionRows 参数从 app host 的 appsettings.json 中的 Parameters 配置节中读取。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Aspire.Hosting.Dcp": "Warning"
    }
  },
  "Parameters": {
    "insertionRows": "1"
  }
}

而 Parameters_ApiService 项目消费该 insertionRows 参数,考虑 apiService 项目中的 Program.cs 代码

using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

int insertionRows = builder.Configuration.GetValue<int>("InsertionRows", 1);

builder.AddServiceDefaults();

builder.AddSqlServerDbContext<MyDbContext>("db");

var app = builder.Build();

app.MapGet("/", async (MyDbContext context) =>
{
    // You wouldn't normally do this on every call,
    // but doing it here just to make this simple.
    context.Database.EnsureCreated();

    for (var i = 0; i < insertionRows; i++)
    {
        var entry = new Entry();
        await context.Entries.AddAsync(entry);
    }

    await context.SaveChangesAsync();

    var entries = await context.Entries.ToListAsync();

    return new
    {
        totalEntries = entries.Count,
        entries
    };
});

app.Run();

posted on 2024-04-03 14:19  冠军  阅读(234)  评论(0编辑  收藏  举报