我目前正在试验.NET Aspire.According to docs,Aspire用于简化应用程序中服务之间的连接和通信.Aspire提供的功能之一是,通过 for each 服务赋予一个可以通过它们解析的特殊名称,使服务之间的通信变得容易,从而消除了手动设置端口和匹配地址以使服务连接的需要.

.NET Aspire Quickstart Documentation中,是否解释了您可以在AppHost Project的Program.cs文件中为您的项目设置自定义名称,如下所示:

var builder = DistributedApplication.CreateBuilder (args);

var usersApi = builder
    .AddProject<Projects.Bargeh_Users_API> ("usersapi"); // Setting the name "usersapi" to the project


builder.AddProject<Projects.Bargeh_Main_Wapp> ("bargehmainwapp")
    .WithReference (usersApi)
    .WithReference (smsApi)
    .WithLaunchProfile ("https");

builder.Build ().Run ();

同样,从the documentation开始,您可以在希望访问其他服务的项目中添加以下代码,并让Aspire知道您需要该服务并为您解析该URL:

builder.Services.AddHttpClient<UsersApiHttpClientProvider>(
    static client=> client.BaseAddress = new("http://usersapi"));

然后,你可以在任何你想注射的地方注射UsersApiHttpClientProvider,并使用它.

此方法有效,但仅适用于访问对普通HTTP请求开放的API.问题是,我使用的UsersApi不是REST API,而是GRPC服务.我可以连接到API并向其发送请求,但无法发送真正的GRPC请求.

我的问题是,我如何让我的客户端项目(本例中是Blazor Web App)使用Grpc.Net个包连接到我的后端GRPC服务,而它们之间的连接是由.NET Aspire建立的?

推荐答案

所以,经过2天的调查,与现有模块的实现和大量的try 相比,我想我找到了应该如何做.

AppHost的代码看起来像这样:

using System.Net.Sockets;

var builder = DistributedApplication.CreateBuilder(args);

var server = builder.AddProject<Projects.Server>("server");

var apiservice = builder.AddProject<Projects.AspireHost_ApiService>("apiservice")
    .WithReference(server);


builder.AddProject<Projects.AspireHost_Web>("webfrontend")
    .WithReference(apiservice);

builder.Build().Run();

这里Projects.Server是一个带有Grpc服务器的应用程序.

现在最棘手的部分.在分析MS用于连接其他服务(如SQL Server)的方法后,我可以得出结论,它们使用不同的*Annotation个类,这些类能够将资源(在我的情况下是项目参考)转换为真正的连接字符串,例如从启动设置或IP +端口从运行容器或一些静态值.

根据注释生成的连接字符串可以作为连接字符串传递,也可以作为环境变量传递.

两者都可以从IConfiguration读取,因为默认的应用程序构建器通过默认的环境变量配置源连接.

例如,.AddSqlServerContainer(...).AddSqlServerConnection(...) Producer生成具有注册名称的连接字符串.

.WithReference(<project>)生成服务注释.因此,您必须获得如下所示的连接字符串

_configuration.GetValue<string>("services:service:1")

作为替代方案,您可以使用选项模式方法进行绑定. 已经实现的客户端代码使用绑定到某些特定部分来 Select 主要的设置集并将其放入Settings类,然后使用IConfiguration类上的.GetConnectionString()方法手动解析连接字符串,然后将连接字符串分配给Settings类.

因此,我得出结论,GRPC通道和客户端应该构造为

IConfiguration configuration = ???;
var conntectionString = configuration.GetValue<string>("services:service:1");
using var channel = GrpcChannel.ForAddress(conntectionString );
var client = new Greeter.GreeterClient(channel);
...

工厂或其他机制来做到这一点,如您的口味.

重要提示:对我来说,.WithReference()会生成两个连接字符串,如下所示:

services__server__0 http://_http.localhost:55224
services__server__1 http://localhost:55224

第一个问题不能在本地使用,因为无法解决.第二个包含的端口不同于我在Aspire UI中看到的端口,也不同于你在launchSettings.json中看到的端口,但它实际上是有效的.我还不知道我有两个URL的确切原因,但至少我可以手动修改一个,或者跳过一个从http://_http开始的URL

从理论上讲,在Host中添加注册项目后,您可以使用.WithAnotation()添加自己的批注,或者使用相同的方法重用现有批注.例如,该注释可能还会生成连接字符串,您将能够使用该连接字符串.

我希望这对你有帮助.

最新情况: 看起来有两个URL是故意的行为,其中一个是他们所说的"命名端点".见named-endpoints

Csharp相关问答推荐

.NET框架4.7.2项目如何引用.NET Core 2.2库?

CsWin32如何创建PWSTR的实例,例如GetWindowText

如何模拟耐久任务客户端在统一测试和获取错误在调度NewsListationInstanceAsync模拟设置

在实时数据库中匹配两个玩家的问题

如何定义EFCore中的多个穿透

如何使用C#获取FireStore中的列表输出文档

如何将字符串变量传递给JObject C#-无法加载文件或程序集';System.Text.Json

VS 2022 for ASP.NET Core中缺少自定义项模板

Lambda表达式如何与隐式强制转换一起工作?

当使用Dapper映射DBNull时,我可以抛出异常吗?

如何使用用于VS代码的.NET Maui扩展在我的iOS/Android设备或模拟器上进行调试?

Google OAuth令牌交换在.Net中不起作用

Blazor Server/.NET 8/在初始加载时调用异步代码是否冻结屏幕,直到第一次异步调用完成?

用于获取字符串的最后12个字符的正则表达式(空格除外)

C#中使用ReadOnlySpan的泛型类型推理

如何对正方形格线进行对角分组

这是T自身的布尔表达式是什么意思?

在Swagger中显示自定义属性的属性名称

自定义ConsoleForMatter中的DI/Http上下文

如何通过WinSCP判断SFTP会话中使用的加密算法?