微服务新体验之Aspire初体验

安装aspire

查看vs版本

我这的版本是17.9.7,不支持aspire,所以需要升级

更新VS

点击 帮助->检查更新

点击更新

静等安装升级

创建aspire项目

项目创建成功,如下图

运行Aspire项目

在AspireApp1.AppHost的launchSettings.json文件中加 "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"

json 复制代码
{
  "$schema": "https://json.schemastore.org/launchsettings.json",
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:15177",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "DOTNET_ENVIRONMENT": "Development",
        "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19239",
        "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20241",
        "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
      }
    }
  }
}

运行AspireApp1.AppHost项目

访问AspireApp1.Web项目

这里只要运行AspireApp1.AppHost项目就可以了

分析

看AspireApp1.AppHost项目的Program.cs文件,这里运行了两个项目

c# 复制代码
var builder = DistributedApplication.CreateBuilder(args);

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

var apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice"); //这里是后端项目

builder.AddProject<Projects.AspireApp1_Web>("webfrontend")//这里是前端项目
    .WithExternalHttpEndpoints()
    .WithReference(cache)
    .WithReference(apiService);

builder.Build().Run();

AspireApp1.Web这里注入了对apiservice的访问

c# 复制代码
using AspireApp1.Web;
using AspireApp1.Web.Components;

var builder = WebApplication.CreateBuilder(args);

// Add service defaults & Aspire components.
builder.AddServiceDefaults();
builder.AddRedisOutputCache("cache");

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddHttpClient<WeatherApiClient>(client => client.BaseAddress = new("http://apiservice")); //这里注入后端项目的API服务

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
}

app.UseStaticFiles();
app.UseAntiforgery();

app.UseOutputCache();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapDefaultEndpoints();

app.Run();

看WeatherApiClient.cs文件

c# 复制代码
namespace AspireApp1.Web;

public class WeatherApiClient(HttpClient httpClient)
{
    public async Task<WeatherForecast[]> GetWeatherAsync(int maxItems = 10, CancellationToken cancellationToken = default)
    {
        List<WeatherForecast>? forecasts = null;

        await foreach (var forecast in httpClient.GetFromJsonAsAsyncEnumerable<WeatherForecast>("/weatherforecast", cancellationToken))//调用后端API获取天气预报数据
        {
            if (forecasts?.Count >= maxItems)
            {
                break;
            }
            if (forecast is not null)
            {
                forecasts ??= [];
                forecasts.Add(forecast);
            }
        }

        return forecasts?.ToArray() ?? [];
    }
}

public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

作者

吴晓阳 微信号:shiningrise