包括:仅限于—
Client集成不包括
注释
此集成是 .NET.NET Aspire 社区工具包 的一部分, 不受 .NET.NET Aspire 团队正式支持。
分布式应用程序运行时(Dapr) 提供了开发人员 API,这些 API 充当与其他服务和依赖项交互的管道,并从这些服务和依赖项的特定内容中抽象化应用程序。 Dapr 和 .NET Aspire 可以协同工作,改善本地开发体验。 通过将 Dapr 与 .NET Aspire结合使用,可以专注于编写和实现基于 .NET的分布式应用程序,而不是本地载入。
本指南介绍如何利用 Dapr的抽象和 .NET Aspire的有意见配置云技术来大规模生成简单、可移植、可复原且安全的微服务。
比较 .NET Aspire 和 Dapr
乍一看,Dapr 和 .NET Aspire 似乎具有重叠的功能,确实如此。 但是,它们采用不同的方法。 .NET .NET Aspire 对如何在云平台上生成分布式应用程序并重点改进本地开发体验有意见。 Dapr 是一种运行时,用于在开发和生产过程中抽象化基础云平台的常见复杂性。 它依赖于 sidecars 来为配置、秘密管理和消息传递等提供抽象。 可以通过配置文件轻松切换基础技术,而代码不需要更改。
方面 | .NET Aspire | Dapr |
---|---|---|
目的 | 旨在更轻松地在本地开发计算机上开发云原生解决方案。 | 旨在更轻松地开发和运行具有可以轻松交换的常见 API 的分布式应用。 |
应用程序接口 | 开发人员必须使用其特定的 SDK 调用资源 API | 开发人员在 Dapr sidecar 中调用 API,后者将调用转发到正确的 API。 无需更改微服务中的代码即可轻松交换资源 API。 |
语言 | 可以使用 .NET 语言、Go、Python、Javascript 等语言编写微服务。 | 可以使用支持 HTTP/gRPC 接口的任何语言调用 Dapr sidecar 函数。 |
安全策略 | 不包括安全策略,但可以安全地配置依赖资源之间的连接。 | 包括可自定义的安全策略,用于控制哪些微服务有权访问其他服务或资源。 |
部署 | 有用于 Azure 和 Kubernetes的部署工具。 | 不包括部署工具。 应用通常使用持续集成/持续开发(CI/CD)系统进行部署。 |
仪表盘 | 提供对资源及其遥测数据的全面视图,并支持侦听任何支持OTEL的资源。 | 仅限于 Dapr 资源。 |
.NET Aspire 通过提供简单的 API 来配置 Dapr 侧车,并将这些侧车作为资源显示在仪表板中,使设置和调试 Dapr 应用程序更加容易。
使用 Dapr 探索 .NET Aspire 组件
Dapr 提供了许多 内置组件,在 Dapr 与 .NET Aspire 一起使用时,可以轻松浏览和配置这些组件。 不要将这些组件与 .NET.NET Aspire 集成混淆。 例如,请考虑以下事项:
-
Dapr— 状态存储:调用
AddDaprStateStore
将配置的状态存储添加到 .NET.NET Aspire 项目中。 -
Dapr— Pub Sub:调用
AddDaprPubSub
,将配置的 pub 子订阅添加到 .NET.NET Aspire 项目。 -
Dapr— 组件:调用
AddDaprComponent
,将已配置的集成添加到您的 .NET.NET Aspire 项目。
安装 Dapr
此集成需要 Dapr 1.13 或更高版本。 若要安装 Dapr,请参阅 安装 Dapr CLI。 安装 Dapr CLI 后,请运行 dapr init
,如本地环境中 初始化 Dapr 中所述。
重要
如果尝试在没有 .NET Aspire CLI 的情况下运行 Dapr 解决方案,将收到以下错误:
Unable to locate the Dapr CLI.
托管集成
在.NET Aspire解决方案中,若要集成Dapr并访问其类型和 API,请在应用主机项目中添加📦 CommunityToolkit.Aspire.Hosting.Dapr NuGet 包。
dotnet add package CommunityToolkit.Aspire.Hosting.Dapr
有关详细信息,请参阅 dotnet 添加包 或 管理 .NET 应用程序中的包依赖性。
将 Dapr sidecar 添加到 .NET Aspire 资源中
Dapr 使用 侧车模式。 Dapr sidecar 作为轻量级、可移植和无状态 HTTP 服务器与应用一起运行,该服务器侦听来自应用的传入 HTTP 请求。
若要将辅助车添加到 .NET.NET Aspire 资源,请对其调用 WithDaprSidecar
方法。
appId
参数是 Dapr 应用程序的唯一标识符,但它是可选的。 如果未提供 appId
,则改用父资源名称。
using Aspire.Hosting.Dapr;
var builder = DistributedApplication.CreateBuilder(args);
var apiService = builder
.AddProject<Projects.Dapr_ApiService>("apiservice")
.WithDaprSidecar();
配置 Dapr 侧车组件
WithDaprSidecar
方法提供多种重载以配置 Dapr 的 sidecar 选项,例如 AppId
和不同的端口。 在以下示例中,Dapr sidecar 配置了用于 GRPC、HTTP、度量、以及特定应用 ID 的具体端口。
DaprSidecarOptions sidecarOptions = new()
{
AppId = "FirstSidecar",
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder.AddProject<Projects.Dapr_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(apiService)
.WithDaprSidecar(sidecarOptions);
完成 Dapr 应用主机示例
将所有内容组合在一起,请考虑以下 .NET.NET Aspire 应用主机项目的示例,其中包括:
- 一个后端 API 服务,用于声明具有默认值的 Dapr sidecar。
- 一个 Web 前端项目,用于声明具有特定选项的 Dapr 辅助进程,例如指定端口。
using Aspire.Hosting.Dapr;
var builder = DistributedApplication.CreateBuilder(args);
var apiService = builder
.AddProject<Projects.Dapr_ApiService>("apiservice")
.WithDaprSidecar();
DaprSidecarOptions sidecarOptions = new()
{
AppId = "FirstSidecar",
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder.AddProject<Projects.Dapr_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(apiService)
.WithDaprSidecar(sidecarOptions);
builder.Build().Run();
启动 .NET Aspire 解决方案时,仪表板将显示 Dapr 侧车作为资源,其状态和日志。
在使用 Dapr 项目中使用 .NET Aspire sidecar
若要从 Dapr 资源使用 .NET Aspire API,可以使用 📦Dapr的 .AspNetCore/ NuGet 包。 Dapr SDK 提供了一组 API 来与 Dapr sidecars 进行交互。
注释
使用 Dapr.AspNetCore
库进行 Dapr 与 ASP.NET 的集成(DI 集成、订阅注册等)。 非ASP.NET 应用(如控制台应用)只能使用 📦Dapr。Client 通过 Dapr 侧车进行呼叫。
dotnet add package Dapr.AspNetCore
添加 Dapr 客户端
安装到 ASP.NET Core 项目中后,可以将 SDK 添加到服务生成器。
builder.Services.AddDaprClient();
调用 Dapr 方法
现可将 DaprClient
实例注入到您的服务中,通过 Dapr SDK 与 Dapr sidecar 交互。
using Dapr.Client;
namespace Dapr.Web;
public class WeatherApiClient(DaprClient client)
{
public async Task<WeatherForecast[]> GetWeatherAsync(
int maxItems = 10, CancellationToken cancellationToken = default)
{
List<WeatherForecast>? forecasts =
await client.InvokeMethodAsync<List<WeatherForecast>>(
HttpMethod.Get,
"apiservice",
"weatherforecast",
cancellationToken);
return forecasts?.Take(maxItems)?.ToArray() ?? [];
}
}
public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
InvokeMethodAsync
是向 Dapr sidecar 发送 HTTP 请求的方法。 它是一种泛型方法,需要:
- HTTP 动词。
- 要调用的服务的Dapr应用 ID。
- 方法名称。
- 取消令牌。
根据 HTTP 谓词,它还可以接收请求正文和标头。 泛型类型参数是响应正文的类型。
前端项目的完整 Program.cs 文件显示:
- 在服务生成器中添加 Dapr 客户端。
- 使用
WeatherApiClient
客户端的 Dapr 类来调用后端服务。
using Dapr.Web;
using Dapr.Web.Components;
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire components.
builder.AddServiceDefaults();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddOutputCache();
builder.Services.AddDaprClient();
builder.Services.AddTransient<WeatherApiClient>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseOutputCache();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.MapDefaultEndpoints();
app.Run();
例如,在 Blazor 项目中,可以将 WeatherApiClient
类注入到 razor 页面中,并使用它调用后端服务:
@page "/weather"
@attribute [StreamRendering(true)]
@attribute [OutputCache(Duration = 5)]
@inject WeatherApiClient WeatherApi
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data loaded from a backend API service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await WeatherApi.GetWeatherAsync();
}
}
使用 Dapr SDK 时,会通过 HTTP 调用 Dapr sidecar。 然后,Dapr 边车将请求转发到目标服务。 虽然目标服务在与 sidecar 的单独进程中运行,但服务相关的集成都在 Dapr sidecar 中运行,负责发现服务并将请求路由到目标服务。