微服務新體驗之Aspire初體驗

shiningrise發表於2024-05-30

安裝aspire

檢視vs版本

我這的版本是17.9.7,不支援aspire,所以需要升級

更新VS

點選 幫助->檢查更新

點選更新

靜等安裝升級

建立aspire專案

專案建立成功,如下圖

執行Aspire專案

在AspireApp1.AppHost的launchSettings.json檔案中加 "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"

{
  "$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檔案,這裡執行了兩個專案

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的訪問

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檔案

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