.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();