Healnet.Infrastructure
2.0.0
See the version list below for details.
dotnet add package Healnet.Infrastructure --version 2.0.0
NuGet\Install-Package Healnet.Infrastructure -Version 2.0.0
<PackageReference Include="Healnet.Infrastructure" Version="2.0.0" />
<PackageVersion Include="Healnet.Infrastructure" Version="2.0.0" />
<PackageReference Include="Healnet.Infrastructure" />
paket add Healnet.Infrastructure --version 2.0.0
#r "nuget: Healnet.Infrastructure, 2.0.0"
#:package Healnet.Infrastructure@2.0.0
#addin nuget:?package=Healnet.Infrastructure&version=2.0.0
#tool nuget:?package=Healnet.Infrastructure&version=2.0.0
Healnet.Infrastructure 基础设施模块
版本: v1.7.2 | 模块: Healnet.Infrastructure | 依赖: Healnet.Core
概述
Healnet.Infrastructure 是 Healnet 微服务框架的基础设施层,对 24+ 个 中间件/基础设施组件进行了统一封装,提供一致的 DI 注册方式与配置约定,业务系统通过简单的 AddXxx 扩展方法即可集成。
v1.7.2 修复:
- 🐛 消除所有编译警告 - 修复 52 个编译警告(NU1603、NU1902/03/04、MSB3539、CS0618)
- 🐛 更新包版本 - 所有 NuGet 包更新为具体版本号,避免版本降级警告
- 🐛 修复输出路径设置 - 使用 Directory.Build.props 统一设置输出路径,消除 MSB3539 警告
v1.7.2 修复:
- 🐛 修复 GrpcOperationFilter 空引用 bug - 确保
operation.Tags和operation.Extensions不为 null
v1.7.0 新增功能:
- ✅ Consul 便捷调用 -
IConsulHttpClient自动服务发现 + 负载均衡,UseConsul一行代码注册服务 - ✅ YARP 配置文件驱动 -
AddYarpConsulDiscovery(IConfiguration)从 appsettings.json 读取服务映射 - ✅ YARP 弹性策略 -
AddYarpResilience()集成 Polly 重试/熔断/限流 - ✅ Swagger gRPC 支持 - gRPC JSON Transcoding,自动将 gRPC 方法映射为 REST HTTP 端点
快速导航
| 类别 | 模块 | 注册方法 | 配置节点 | 生命周期 |
|---|---|---|---|---|
| 认证安全 | Authentication | AddJwtAuth(...) |
Healnet:Jwt |
Scoped/Singleton |
| 认证安全 | Security | AddSecurityHeaders(...) / AddCorsPolicy(...) |
Healnet:Security / Healnet:Cors |
Singleton |
| 数据存储 | SqlSugar | AddSqlSugar(...) |
Healnet:SqlSugar |
Singleton |
| 数据存储 | MongoDB | 手动注册 IMongoClient + IMongoDbContext |
自定义 | Singleton |
| 数据存储 | ClickHouse | AddClickHouse(...) |
Healnet:ClickHouse |
Scoped |
| 数据存储 | ElasticSearch | AddElasticSearch(...) |
Healnet:ElasticSearch |
Singleton |
| 缓存锁 | Redis | AddRedis(...) |
Healnet:Redis |
Singleton |
| 消息队列 | RabbitMQ | 手动注册 IConnection + IRabbitMQService |
自定义 | Singleton |
| 服务发现 | Consul | AddConsul(...) |
Healnet:Consul |
Singleton |
| HTTP 客户端 | Http | AddHttpClientService(...) |
Healnet:HttpClient:{name} |
Scoped |
| API 网关 | YARP | AddYarpConfigBuilder() / AddYarpConsulDiscovery(...) |
代码配置 | Transient/Singleton |
| RPC | gRPC | AddGrpcService(...) |
Healnet:gRPC |
Singleton |
| 可观测性 | Logging | UseHealnetSerilog() / AddSerilog(...) |
Healnet:Serilog |
Singleton |
| 可观测性 | OpenTelemetry | AddHealnetOpenTelemetry(...) |
代码配置 | Singleton |
| 可观测性 | HealthChecks | AddHealnetHealthChecks(...) + MapHealnetHealthChecks() |
代码配置 | Transient |
| 可观测性 | Middleware | UseExceptionHandling() / UseRequestLogging() / UseCorrelationId() |
代码配置 | Transient |
| 容错 | Resilience | AddResilience(...) |
代码配置 | Singleton |
| 容错 | AOP 拦截器 | AddAspectCoreWithInterceptors() |
代码配置 | Scoped |
| API 文档 | Swagger | AddSwagger(...) + UseSwaggerWithUI() |
Healnet:Swagger |
Singleton |
| 对象存储 | OSS | AddAliyunOssFileService(...) |
Healnet:FileStorage |
Singleton |
| AI 集成 | AI | AddAIServices(...) |
Healnet:AI |
Scoped |
| 工作单元 | UnitOfWork | AddUnitOfWork() |
无 | Scoped |
通用入口
对于只需要常用基础服务的场景,提供了快捷注册入口:
// Program.cs
builder.Services.AddHealnetInfrastructure(options =>
{
options.HttpClientName = "default";
options.ConsulAddress = "http://consul.healnet.net:8500";
});
// 或仅基础通用服务(Serilog + SnowflakeId)
builder.Services.AddHealnetCommonServices();
模块详细说明
1. JWT 认证 (Healnet.Infrastructure.Authentication)
JwtOptions 配置项:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
SecretKey |
string |
"" |
JWT 签名密钥(必须 ≥ 32 字符) |
Issuer |
string |
Healnet |
Token 签发者 |
Audience |
string |
Healnet.Api |
Token 受众 |
AccessTokenExpireMinutes |
int |
60 |
Access Token 过期时间(分钟) |
RefreshTokenExpireDays |
int |
7 |
Refresh Token 过期时间(天) |
ValidateIssuer |
bool |
true |
是否验证签发者 |
ValidateAudience |
bool |
true |
是否验证受众 |
ValidateLifetime |
bool |
true |
是否验证有效期 |
ValidateIssuerSigningKey |
bool |
true |
是否验证签名密钥 |
注册方式:
// 方式一:配置委托
builder.Services.AddJwtAuth(options =>
{
options.SecretKey = "your-32-char-minimum-secret-key!!";
options.Issuer = "Healnet";
options.Audience = "Healnet.Api";
options.AccessTokenExpireMinutes = 60;
options.RefreshTokenExpireDays = 7;
});
// 方式二:配置文件
builder.Services.AddJwtAuth(builder.Configuration);
// 中间件(必须)
app.UseAuthentication();
app.UseAuthorization();
配置示例 (appsettings.json):
{
"Healnet": {
"Jwt": {
"SecretKey": "your-secret-key-at-least-32-characters-long!!",
"Issuer": "Healnet",
"Audience": "Healnet.Api",
"AccessTokenExpireMinutes": 60,
"RefreshTokenExpireDays": 7,
"ValidateIssuer": true,
"ValidateAudience": true,
"ValidateLifetime": true,
"ValidateIssuerSigningKey": true
}
}
}
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
JwtHelper |
JwtHelper |
Scoped | Token 生成及验证 |
ITokenService |
TokenService |
Scoped | Token 管理(生成/刷新/撤销) |
JwtHelper API:
public class JwtHelper
{
string GenerateToken(IEnumerable<Claim> claims); // 生成 JWT Token
ClaimsPrincipal? ValidateToken(string token); // 验证 Token
string? GetClaimValue(string token, string claimType); // 获取声明值
long? GetUserId(string token); // 获取用户 ID
string? GetEmail(string token); // 获取邮箱
bool IsTokenValid(string token); // Token 是否有效
}
⚠️
SecretKey必须 ≥ 32 字符,注册时自动校验,不满足会抛出ArgumentException。
2. 安全头与 CORS (Healnet.Infrastructure.Security)
SecurityOptions 配置项:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
EnableHsts |
bool |
true |
是否启用 HSTS(HTTP 严格传输安全) |
HstsMaxAgeDays |
int |
365 |
HSTS 最大有效期(天) |
EnableCsp |
bool |
false |
是否启用 CSP(内容安全策略) |
ContentSecurityPolicy |
string |
default-src 'self'; |
CSP 策略内容 |
EnableXssProtection |
bool |
true |
是否启用 XSS 保护 |
EnableFrameOptions |
bool |
true |
是否启用 Frame 选项 |
FrameOptionsValue |
string |
DENY |
Frame 选项值(DENY/SAMEORIGIN) |
EnableXContentTypeOptions |
bool |
true |
是否启用 X-Content-Type-Options |
ReferrerPolicy |
string |
strict-origin-when-cross-origin |
Referrer-Policy 响应头值 |
PermissionsPolicy |
string? |
null |
Permissions-Policy 响应头值 |
CustomHeaders |
Dictionary<string, string> |
[] |
自定义响应头 |
CorsOptions 配置项:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
AllowedOrigins |
List<string> |
[] |
允许的源 |
AllowedMethods |
List<string> |
["GET", "POST", "PUT", "DELETE"] |
允许的 HTTP 方法 |
AllowedHeaders |
List<string> |
["Authorization", "Content-Type"] |
允许的请求头 |
AllowCredentials |
bool |
false |
是否允许凭证 |
PreflightMaxAgeMinutes |
int |
10 |
预检请求缓存时间(分钟) |
安全头注册:
// 默认安全头(XSS、Frame、HSTS、CSP 等)
builder.Services.AddSecurityHeaders();
app.UseSecurityHeaders();
// 自定义
builder.Services.AddSecurityHeaders(options =>
{
options.EnableHsts = true;
options.EnableCsp = true;
options.ContentSecurityPolicy = "default-src 'self'; script-src 'self' 'unsafe-inline';";
});
// 从配置读取
builder.Services.AddSecurityHeaders(builder.Configuration);
app.UseSecurityHeaders();
配置示例:
{
"Healnet": {
"Security": {
"EnableHsts": false,
"EnableXssProtection": true,
"EnableFrameOptions": true,
"FrameOptionsValue": "DENY",
"EnableCsp": false,
"EnableXContentTypeOptions": true,
"ReferrerPolicy": "strict-origin-when-cross-origin"
},
"Cors": {
"AllowedOrigins": ["http://localhost:3000"],
"AllowCredentials": true,
"AllowedMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"AllowedHeaders": ["Content-Type", "Authorization", "X-Requested-With"]
}
}
}
⚠️ 注意:
UseSecurityHeaders()必须在UseCors()之前调用- 开发环境建议禁用 HSTS(
EnableHsts = false)- 如果
AllowCredentials = true,则AllowedOrigins不能包含*
CORS 注册:
// 从配置读取
builder.Services.AddCorsPolicy(builder.Configuration, "DefaultPolicy");
app.UseCorsPolicy("DefaultPolicy");
// 手动配置
builder.Services.AddCorsPolicy("MyPolicy", policy =>
{
policy.WithOrigins("https://app.example.com")
.AllowCredentials()
.WithMethods("GET", "POST");
});
3. SqlSugar ORM (Healnet.Infrastructure.SqlSugar)
注册方式:
// 方式一:连接字符串(默认 MySQL)
builder.Services.AddSqlSugar("Server=192.168.114.213;Database=KP_BRM;Uid=sa;Pwd=xxx;");
// 方式二:配置委托
builder.Services.AddSqlSugar(options =>
{
options.ConnectionString = "Server=...";
options.DbType = DbType.SqlServer;
options.IsAutoCloseConnection = true;
options.InitKeyType = InitKeyType.Attribute;
});
// 方式三:配置文件
builder.Services.AddSqlSugar(builder.Configuration);
配置示例:
{
"Healnet": {
"SqlSugar": {
"ConnectionString": "Server=192.168.114.213;Database=KP_BRM;Uid=sa;Pwd=xxx;",
"DbType": "SqlServer",
"IsAutoCloseConnection": true,
"InitKeyType": "Attribute"
}
}
}
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
ISqlSugarClient |
SqlSugarClient |
Singleton | ORM 操作(SQL 日志/错误自动上报) |
注册实体仓储:
// 单个实体
builder.Services.AddSqlSugarRepository<User>();
// 批量注册
builder.Services.AddSqlSugarRepositories(typeof(User), typeof(Order), typeof(Product));
// 使用
public class UserService
{
private readonly ISqlSugarRepository<User> _repo;
public UserService(ISqlSugarRepository<User> repo) => _repo = repo;
}
ISqlSugarRepository<T> 方法:
Task<T> GetByIdAsync(object id);
Task<List<T>> GetAllAsync();
Task<List<T>> GetListAsync(Expression<Func<T, bool>> where);
Task<T> GetSingleAsync(Expression<Func<T, bool>> where);
Task<int> InsertAsync(T entity);
Task<int> InsertRangeAsync(List<T> entities);
Task<int> UpdateAsync(T entity);
Task<int> UpdateRangeAsync(List<T> entities);
Task<int> DeleteByIdAsync(object id);
Task<int> DeleteAsync(Expression<Func<T, bool>> where);
Task<int> CountAsync(Expression<Func<T, bool>> where);
Task<List<T>> PageAsync(int page, int size, Expression<Func<T, bool>> where, ...);
4. MongoDB (Healnet.Infrastructure.MongoDB)
MongoDB 模块采用手动 DI 注册方式,提供灵活的多租户上下文。
注册方式:
// 注册 MongoClient
builder.Services.AddSingleton<IMongoClient>(sp =>
new MongoClient("mongodb://localhost:27017"));
// 注册配置
builder.Services.AddSingleton(new MongoDbContextOptions
{
DefaultDatabase = "HealnetDB",
EnableAudit = true,
TenantDatabases = new List<TenantDatabase>
{
new() { TenantId = "tenant1", DatabaseName = "HealnetDB_Tenant1" }
}
});
// 注册上下文
builder.Services.AddSingleton<IMongoDbContext, MongoDbContext>();
// 注册审计处理
builder.Services.AddSingleton<IAuditHandler, AuditHandler>();
注入服务:
| 接口 | 实现 | 用途 |
|---|---|---|
IMongoDbContext |
MongoDbContext |
数据库上下文,支持多租户、集合获取 |
IAuditHandler |
AuditHandler |
审计字段自动设置(CreatedAt/CreatedBy/UpdatedAt/UpdatedBy) |
使用示例:
public class UserRepository
{
private readonly IMongoDbContext _context;
public UserRepository(IMongoDbContext context) => _context = context;
public async Task<User> GetById(string id)
{
var collection = _context.GetCollection<User>();
return await collection.Find(u => u.Id == id).FirstOrDefaultAsync();
}
public async Task Insert(User user)
{
// 审计处理由 AuditHandler 在 MongoDbContext 层自动完成
var collection = _context.GetCollection<User>();
await collection.InsertOneAsync(user);
}
}
6. ElasticSearch (Healnet.Infrastructure.ElasticSearch)
注册方式:
// 配置委托
builder.Services.AddElasticSearch(options =>
{
options.Uri = "http://192.168.114.206:9200";
options.DefaultIndex = "healnet-logs";
options.Username = "elastic";
options.Password = "password";
});
// 配置文件
builder.Services.AddElasticSearch(builder.Configuration);
配置示例:
{
"Healnet": {
"ElasticSearch": {
"Uri": "http://192.168.114.206:9200",
"DefaultIndex": "healnet-logs",
"Username": "elastic",
"Password": "password",
"EnableSniffing": false,
"TimeoutSeconds": 30,
"ConnectionLimit": 10
}
}
}
注入服务:
| 接口 | 实现 | 用途 |
|---|---|---|
IElasticClient |
ElasticClient (NEST) |
ElasticSearch 低级客户端 |
IElasticSearchService |
ElasticSearchService |
全文搜索、聚合查询封装 |
7. Redis 缓存与分布式锁 (Healnet.Infrastructure.Redis)
RedisOptions 配置项:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Configuration |
string |
localhost:6379 |
Redis 连接字符串 |
KeyPrefix |
string |
Healnet: |
缓存键前缀(从配置读取) |
ConnectTimeout |
int |
5000 |
连接超时(毫秒) |
SyncTimeout |
int |
5000 |
同步超时(毫秒) |
AbortOnConnectFail |
bool |
false |
连接失败时是否中止 |
DefaultDatabase |
int |
0 |
默认数据库编号 |
注册方式:
// 配置委托
builder.Services.AddRedis(options =>
{
options.Configuration = "192.168.114.233:6379,defaultDatabase=0";
options.KeyPrefix = "Healnet:Identity:";
options.ConnectTimeout = 5000;
options.SyncTimeout = 5000;
options.AbortOnConnectFail = false;
options.DefaultDatabase = 0;
});
// 配置文件
builder.Services.AddRedis(builder.Configuration);
配置示例:
{
"Healnet": {
"Redis": {
"Configuration": "192.168.114.233:6379,defaultDatabase=0",
"KeyPrefix": "Healnet:Identity:",
"ConnectTimeout": 5000,
"SyncTimeout": 5000,
"AbortOnConnectFail": false,
"DefaultDatabase": 0
}
}
}
⚠️ 注意:
InstanceName和PoolSize字段在代码里未使用,建议从配置中删除- 如果没有密码,不要写
password=,,直接省略即可KeyPrefix会从配置读取,确保配置正确
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
IConnectionMultiplexer |
ConnectionMultiplexer |
Singleton | Redis 连接 |
IRedisService / ICacheService |
RedisService |
Singleton | 缓存读写、模式匹配、TTL |
IDistributedLockService |
DistributedLockService |
Singleton | 分布式锁(SETNX + Lua 原子释放) |
IRedisService 核心 API:
// ICacheService 基础方法
Task SetAsync<T>(string key, T value, TimeSpan? expiry = null);
Task<T?> GetAsync<T>(string key);
Task<T?> GetOrSetAsync<T>(string key, Func<Task<T>> factory, TimeSpan? expiry = null);
Task RemoveAsync(string key);
Task<bool> ExistsAsync(string key);
// IRedisService 扩展方法
Task RefreshAsync(string key, TimeSpan expiry); // 刷新过期时间
Task<List<string>> GetKeysByPatternAsync(string pattern); // SCAN 模式匹配
Task RemoveByPatternAsync(string pattern); // 批量删除(Pipeline)
Task ClearAsync(); // FLUSHDB(危险操作)
Task<long> GetTtlAsync(string key); // 剩余 TTL(秒)
string KeyPrefix { get; set; } // 键前缀(默认 "Healnet:")
🔒 安全特性: 释放锁使用 Lua 脚本
GET + DEL原子校验锁值,防止误删他人持有的锁;锁值通过AsyncLocal上下文隔离存储。
8. RabbitMQ 消息队列 (Healnet.Infrastructure.RabbitMQ)
注册方式:
// 注册 RabbitMQ 连接
builder.Services.AddSingleton<IConnection>(sp =>
{
var factory = new ConnectionFactory
{
HostName = "192.168.114.206",
UserName = "guest",
Password = "guest",
VirtualHost = "/"
};
return factory.CreateConnection();
});
// 注册服务
builder.Services.AddSingleton<IRabbitMQService, RabbitMQService>();
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
IRabbitMQService |
RabbitMQService |
Singleton | 消息发布、订阅、队列/交换机管理 |
核心 API:
// 消息发布
void Publish<T>(string exchange, string routingKey, T message);
Task PublishAsync<T>(string exchange, string routingKey, T message);
// 消息订阅
void Subscribe<T>(string queue, Func<T, Task> handler);
Task SubscribeAsync<T>(string queue, Func<T, Task> handler);
// 队列管理
void DeclareQueue(string queue, bool durable = true, bool exclusive = false, bool autoDelete = false);
void DeclareExchange(string exchange, string type = "direct");
void BindQueue(string queue, string exchange, string routingKey);
void PurgeQueue(string queue);
void DeleteQueue(string queue);
void DeleteExchange(string exchange);
bool IsConnected { get; }
void Initialize();
9. Consul 服务发现 (Healnet.Infrastructure.Consul)
注册方式:
// 直接指定地址
builder.Services.AddConsul("http://consul.healnet.net:8500");
// 配置委托
builder.Services.AddConsul(options =>
{
options.Address = "http://consul.healnet.net:8500";
});
// 配置文件
builder.Services.AddConsul(builder.Configuration);
配置示例:
{
"Healnet": {
"Consul": {
"Address": "http://consul.healnet.net:8500"
}
}
}
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
IConsulService |
ConsulService |
Singleton | 服务注册、发现、KV 存储、健康检查 |
10. HTTP 客户端 (Healnet.Infrastructure.Http)
内置 重试(指数退避 2^n 秒)、熔断(阈值 5 次/30 秒)、超时(30 秒)三种 Polly 策略。
注册方式:
// 最简
builder.Services.AddHttpClientService();
// 带 BaseAddress
builder.Services.AddHttpClientService(client =>
{
client.BaseAddress = new Uri("https://api.example.com");
client.DefaultRequestHeaders.Add("Accept", "application/json");
});
// 自定义弹性策略
builder.Services.AddHttpClientService(
client => client.BaseAddress = new Uri("https://api.example.com"),
options =>
{
options.MaxRetries = 5;
options.TimeoutSeconds = 60;
options.CircuitBreakerThreshold = 10;
});
// 泛型客户端
builder.Services.AddHttpClientService<IMyApiClient, MyApiClient>("my-api");
// 从配置读取(支持 Consul 服务发现集成)
builder.Services.AddHttpClientService(builder.Configuration, "default");
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
IHttpClientService |
HttpClientService |
Scoped | HTTP 调用(GET/POST/PUT/DELETE) |
IHttpClientFactoryService |
HttpClientFactoryService |
Singleton | HttpClient 工厂 |
配置示例:
{
"Healnet": {
"HttpClient": {
"default": {
"BaseAddress": "https://api.example.com",
"TimeoutSeconds": 30,
"MaxRetries": 3,
"CircuitBreakerThreshold": 5,
"CircuitBreakerDurationSeconds": 30,
"EnableConsulIntegration": false
}
}
}
}
弹性策略 Builder 扩展(用于其他 IHttpClientBuilder):
services.AddHttpClient<ISomeClient, SomeClient>()
.AddResiliencePolicies() // 三合一(重试+熔断+超时)
.AddRetryPolicy(maxRetries: 5) // 仅重试
.AddCircuitBreakerPolicy(10, 60) // 仅熔断
.AddTimeoutPolicy(seconds: 60); // 仅超时
11. YARP API 网关 (Healnet.Infrastructure.YARP)
静态路由:
builder.Services.AddReverseProxy();
builder.Services.AddYarpConfigBuilder();
// 代码配置
builder.Services.AddYarpStaticConfig(options =>
{
options.Routes.Add(new YarpRoute
{
RouteId = "api-route",
ClusterId = "api-cluster",
MatchPath = "/api/{**catch-all}"
});
options.Clusters.Add(new YarpCluster
{
ClusterId = "api-cluster",
Destinations = new() { "http://localhost:5001" }
});
});
Consul 动态服务发现:
builder.Services.AddReverseProxy();
builder.Services.AddYarpConsulDiscovery(options =>
{
options.AddServiceMapping("auth-route", "auth-cluster", "auth-service", "/auth/{**catch-all}");
options.AddServiceMapping("order-route", "order-cluster", "order-service", "/orders/{**catch-all}");
});
YARP 弹性策略(Polly 装饰器):
// 必须在 AddReverseProxy() 之后调用
builder.Services.AddReverseProxy();
builder.Services.AddResilience(); // 注册 IResiliencePolicyProvider
builder.Services.AddYarpResilience(); // 装饰 IHttpForwarder
12. gRPC (Healnet.Infrastructure.gRPC)
// 注册
builder.Services.AddGrpcService();
// 带配置
builder.Services.AddGrpcService(options =>
{
options.EnableConsulIntegration = true;
});
// 从配置
builder.Services.AddGrpcService(builder.Configuration);
配置示例:
{
"Healnet": {
"gRPC": {
"EnableConsulIntegration": false,
"ConsulAddress": "http://localhost:8500",
"DefaultTimeoutSeconds": 30,
"EnableRetry": true,
"MaxRetryAttempts": 3
}
}
}
⚠️
IGrpcService.CallGrpcMethodAsync当前抛出NotSupportedException,需业务系统自行集成 gRPC 客户端调用。
13. 日志 - Serilog (Healnet.Infrastructure.Logging)
推荐方式 — IHostBuilder:
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseHealnetSerilog(); // 自动读取 Healnet:Serilog 配置,注册 ILoggerService
// 启用请求日志
app.UseSerilogRequestLogging();
IServiceCollection 方式:
// 默认控制台 + 文件日志
builder.Services.AddSerilogDefault();
// 自定义
builder.Services.AddSerilog(config =>
{
config.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("logs/app.log");
});
// 从配置文件
builder.Services.AddSerilog(builder.Configuration);
配置示例:
{
"Healnet": {
"Serilog": {
"MinimumLevel": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
},
"Console": {
"Enabled": true,
"OutputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}"
},
"File": {
"Enabled": true,
"Path": "logs/log-.txt",
"RollingInterval": "Day",
"RetainedFileCountLimit": 30,
"OutputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}"
},
"Elasticsearch": {
"Enabled": false,
"NodeUris": "http://localhost:9200",
"IndexFormat": "healnet-logs-{0:yyyy.MM.dd}",
"AutoRegisterTemplate": true
}
}
}
}
日志级别映射:
verbose / trace → Verbose
debug → Debug
information/info → Information
warning/warn → Warning
error → Error
fatal/critical → Fatal
14. OpenTelemetry 可观测性 (Healnet.Infrastructure.OpenTelemetry)
builder.Services.AddHealnetOpenTelemetry(options =>
{
options.Enabled = true;
options.ServiceName = "MyService";
options.ServiceVersion = "1.0.0";
// Trace / Metrics / Logging(默认全开)
options.EnableTracing = true;
options.EnableMetrics = true;
options.EnableLogging = true;
// 导出器
options.Console.Enabled = true;
options.Otlp.Enabled = true;
options.Otlp.Endpoint = "http://jaeger:4317";
options.Jaeger.Enabled = false;
options.Zipkin.Enabled = false;
// 自动埋点
options.InstrumentationNames = new() { "AspNetCore", "HttpClient", "SqlClient" };
});
app.UseHealnetOpenTelemetry();
支持的导出器:
| 导出器 | 配置属性 | 默认地址 |
|---|---|---|
| Console | Console.Enabled |
— |
| OTLP (gRPC) | Otlp.Enabled / Otlp.Endpoint |
http://localhost:4317 |
| Jaeger | Jaeger.Enabled / Jaeger.Host:Port |
localhost:6831 |
| Zipkin | Zipkin.Enabled / Zipkin.Endpoint |
http://localhost:9411/api/v2/spans |
15. 健康检查 (Healnet.Infrastructure.HealthChecks)
// 注册(支持 Redis / MongoDB / RabbitMQ)
builder.Services.AddHealnetHealthChecks(
redisEnabled: true,
mongoEnabled: true,
rabbitMqEnabled: true);
// 映射端点(返回 JSON)
app.MapHealnetHealthChecks("/health");
健康检查响应格式:
{
"Status": "Healthy",
"Checks": [
{
"Name": "redis",
"Status": "Healthy",
"Description": "Redis is connected",
"Duration": 12.5,
"ErrorMessage": null
}
],
"TotalDuration": 25.8
}
16. 中间件 (Healnet.Infrastructure.Middleware)
// 异常处理(自动捕获未处理异常,返回统一 JSON)
app.UseExceptionHandling(showDetailedErrors: false);
// 请求日志(记录请求路径 + 耗时)
app.UseRequestLogging();
// 关联 ID(从 X-Correlation-Id 头读取或自动生成)
app.UseCorrelationId();
// 健康检查端点(自定义路径)
app.UseHealthCheck("/healthz");
⚠️
HealthCheckMiddleware和ExceptionHandlingMiddleware(Infrastructure 版本) 已标记[Obsolete],推荐使用 ASP.NET Core 内置健康检查及 Core 层ExceptionHandlerMiddleware。
17. 弹性策略 (Healnet.Infrastructure.Resilience)
// 默认配置
builder.Services.AddResilience();
// 自定义
builder.Services.AddResilience(options =>
{
options.RetryCount = 5;
options.CircuitBreakerThreshold = 10;
options.CircuitBreakerDurationSeconds = 60;
});
// 注入
public class MyService
{
public MyService(IResiliencePolicyProvider provider)
{
var retryPolicy = provider.GetRetryPolicy();
var circuitBreaker = provider.GetCircuitBreakerPolicy();
}
}
18. AOP 拦截器 (Healnet.Infrastructure.AOP)
基于 AspectCore 提供 5 个内置拦截器:
| 拦截器 | 用途 |
|---|---|
LogInterceptor |
方法调用日志(入参/出参/耗时) |
CacheInterceptor |
方法结果缓存 |
ExceptionHandlerInterceptor |
异常捕获与统一处理 |
PerformanceMonitorInterceptor |
性能监控(慢方法告警) |
RetryInterceptor |
方法重试 |
注册方式:
// 方式一:全部注册
builder.Services.AddAspectCoreWithInterceptors();
// 方式二:选择性注册
builder.Services.AddAspectCore(config =>
{
config.AddLogInterceptor()
.AddExceptionHandlerInterceptor()
.AddPerformanceMonitorInterceptor();
});
// 然后在需要代理的服务上用 [Intercept] 标记
[Intercept(typeof(LogInterceptor))]
public class UserService : IUserService
{
// 所有方法自动记录日志
}
19. Swagger API 文档 (Healnet.Infrastructure.Swagger)
// 注册
builder.Services.AddSwagger(options =>
{
options.Title = "My API";
options.Version = "v1";
options.EnableJwtAuth = true;
options.IncludeXmlComments = true;
});
// 或从配置读取
builder.Services.AddSwagger(builder.Configuration);
// 启用
app.UseSwaggerWithUI(); // 路径: /swagger
配置示例:
{
"Healnet": {
"Swagger": {
"Title": "Healnet API",
"Description": "Healnet 微服务 API 文档",
"Version": "v1",
"EnableJwtAuth": true,
"JwtSchemeName": "Bearer",
"IncludeXmlComments": true,
"DocExpansion": "List",
"DefaultModelExpandDepth": 2
}
}
}
20. 阿里云 OSS 对象存储 (Healnet.Infrastructure.OSS)
// 方式一:简单参数
builder.Services.AddAliyunOssFileService(
endpoint: "oss-cn-hangzhou.aliyuncs.com",
accessKeyId: "your-access-key",
accessKeySecret: "your-secret",
bucketName: "my-bucket");
// 方式二:配置委托
builder.Services.AddAliyunOssFileService(options =>
{
options.OssEndpoint = "oss-cn-hangzhou.aliyuncs.com";
options.OssAccessKeyId = "your-access-key";
options.OssAccessKeySecret = "your-secret";
options.OssBucketName = "my-bucket";
});
// 方式三:配置文件
builder.Services.AddAliyunOssFileService(builder.Configuration);
配置示例:
{
"Healnet": {
"FileStorage": {
"StorageType": "Oss",
"OssEndpoint": "oss-cn-hangzhou.aliyuncs.com",
"OssAccessKeyId": "your-access-key",
"OssAccessKeySecret": "your-secret",
"OssBucketName": "my-bucket",
"BaseUrl": "https://cdn.example.com"
}
}
}
注入服务:
| 接口 | 实现 | 生命周期 | 用途 |
|---|---|---|---|
IFileService |
AliyunOssFileService |
Singleton | 文件上传/下载/删除(替换默认实现) |
21. AI 服务集成 (Healnet.Infrastructure.AI)
支持 Semantic Kernel 和 Microsoft.Extensions.AI 两种 AI 框架,以及 Agent 框架。
// 完整 AI 服务
builder.Services.AddAIServices(options =>
{
options.Provider = AIProvider.SemanticKernel;
options.ApiKey = "sk-xxx";
options.ModelName = "gpt-4o";
options.Endpoint = "https://api.openai.com/v1";
});
// 仅 Semantic Kernel
builder.Services.AddSemanticKernelOnly(options => { ... });
// 仅 Microsoft.Extensions.AI
builder.Services.AddMicrosoftAIOnly(options => { ... });
// 仅 Agent Framework
builder.Services.AddAgentFrameworkOnly(options => { ... });
// 从配置文件
builder.Services.AddAIServices(builder.Configuration);
配置示例:
{
"Healnet": {
"AI": {
"Provider": "SemanticKernel",
"ApiKey": "sk-xxx",
"Endpoint": "https://api.openai.com/v1",
"ModelName": "gpt-4o",
"MaxTokens": 4096,
"Temperature": 0.7,
"TopP": 0.9,
"ContextWindowSize": 128000,
"RAG": {
"Enabled": true,
"TopK": 5,
"MaxContextLength": 8192
},
"AgentFramework": {
"Endpoint": "https://agent.example.com",
"DeploymentName": "my-agent",
"EnableToolCalling": true,
"MaxIterations": 10
}
}
}
}
注入服务:
| 接口 | 实现 | 用途 |
|---|---|---|
IAIService |
UnifiedAIService |
统一 AI 服务入口 |
IChatContextManager |
ChatContextManager |
对话上下文管理 |
IRAGService |
RAGService |
检索增强生成 |
IAgentService |
AgentService |
Agent 服务 |
IAgentContextManager |
AgentContextManager |
Agent 上下文管理 |
ICopilotClient |
CopilotClient / MicrosoftAIClient |
AI 客户端 |
22. 工作单元 (Healnet.Infrastructure.UnitOfWork)
builder.Services.AddUnitOfWork();
// 使用
public class OrderService
{
private readonly IUnitOfWork _uow;
public OrderService(IUnitOfWork uow) => _uow = uow;
public async Task Process()
{
await _uow.BeginTransactionAsync();
try
{
// 业务操作...
await _uow.CommitTransactionAsync();
}
catch
{
await _uow.RollbackTransactionAsync();
throw;
}
}
}
完整配置总览
以下是所有模块在实际 appsettings.json 中的配置结构一览(按需使用):
{
"Healnet": {
"Redis": {
"Configuration": "localhost:6379",
"InstanceName": "Healnet",
"KeyPrefix": "Healnet:",
"ConnectTimeout": 5000,
"SyncTimeout": 5000,
"AbortOnConnectFail": false,
"DefaultDatabase": 0,
"PoolSize": 10
},
"Jwt": {
"SecretKey": "your-secret-key-at-least-32-characters-long!!",
"Issuer": "Healnet",
"Audience": "Healnet.Api",
"AccessTokenExpireMinutes": 60,
"RefreshTokenExpireDays": 7
},
"SqlSugar": {
"ConnectionString": "Server=localhost;Database=MyDB;Uid=root;Pwd=123456;",
"DbType": "MySql",
"IsAutoCloseConnection": true,
"InitKeyType": "Attribute"
},
"ElasticSearch": {
"Uri": "http://localhost:9200",
"DefaultIndex": "healnet-logs",
"Username": "",
"Password": ""
},
"Consul": {
"Address": "http://localhost:8500"
},
"Serilog": {
"MinimumLevel": "Information",
"Console": { "Enabled": true },
"File": { "Enabled": true, "Path": "logs/log-.txt", "RollingInterval": "Day" }
},
"Swagger": {
"Title": "Healnet API",
"Version": "v1",
"EnableJwtAuth": true
},
"Security": {
"EnableHsts": true,
"EnableXssProtection": true
},
"Cors": {
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "POST", "PUT", "DELETE"],
"AllowedHeaders": ["Authorization", "Content-Type"]
},
"AI": {
"Provider": "SemanticKernel",
"ApiKey": "",
"ModelName": "gpt-4o"
},
"FileStorage": {
"StorageType": "Oss",
"OssEndpoint": "",
"OssAccessKeyId": "",
"OssAccessKeySecret": "",
"OssBucketName": ""
},
"gRPC": {
"EnableConsulIntegration": false,
"DefaultTimeoutSeconds": 30
}
}
}
依赖关系
Healnet.Infrastructure (net10.0)
├── Healnet.Core
├── Healnet.Common
├── StackExchange.Redis 2.9.0
├── MongoDB.Driver 2.29.0
├── SqlSugarCore 5.1.4
├── NEST 7.17.5
├── RabbitMQ.Client 6.8.1
├── Consul 1.7.14
├── Yarp.ReverseProxy 2.2.0
├── Grpc.AspNetCore 2.65.0
├── Serilog.AspNetCore 8.0.0
├── OpenTelemetry 1.7.x(Tracing + Metrics + Logging)
├── Polly 8.3.1
├── AspectCore 2.4.0
├── Swashbuckle 6.5.0
├── Microsoft.SemanticKernel 1.67.1
├── Microsoft.Extensions.AI 9.10.0
├── Aliyun.OSS.SDK.NetCore 2.14.1
└── Microsoft.AspNetCore.Authentication.JwtBearer 8.0.8
版本历史
| 版本 | 日期 | 变更 |
|---|---|---|
| 1.0.0 | — | 初始版本 |
| 1.1.0 | — | 添加 Microsoft.Extensions.AI 封装,完善文档 |
| 1.2.0 | 2026-05 | 新增 YARP 弹性策略装饰器、AddYarpResilience;AddSwagger 自动注册 AddEndpointsApiExplorer;UseHealnetSerilog 自动注册 ILoggerService;安全修复(分布式锁原子操作、密码哈希随机盐);gRPC/AI 桩实现改为 NotSupportedException;AOP 拦截器正确注册 |
已知问题与封装改进建议
检查日期: 2026-06-25 检查范围: Healnet.Infrastructure 所有模块 问题总数: 37 个
问题严重程度说明
| 严重程度 | 说明 | 数量 |
|---|---|---|
| 🔴 高 | 会导致运行时错误、数据丢失或安全漏洞 | 4 |
| 🟡 中 | 影响功能完整性、性能或可维护性 | 18 |
| 🟢 低 | 代码规范、文档完善等优化建议 | 15 |
🔴 高优先级问题(需要立即修复)
1. UnitOfWork.SaveChangesAsync 实现不正确
模块: UnitOfWork
文件: UnitOfWork/UnitOfWork.cs
问题: SaveChangesAsync() 方法直接返回 Task.FromResult(0),没有实际保存更改的逻辑
影响: 如果业务代码调用此方法,会误以为更改已保存
修复状态: ✅ 已修复(添加说明注释,SqlSugar 会自动保存更改)
建议: 对于 EF Core 等需要显式保存的 ORM,此方法需要真正实现
2. RabbitMQ 消息反序列化类型不安全
模块: RabbitMQ
文件: RabbitMQConsumerBase.cs
问题: DeserializeMessage<object> 反序列化所有消息为 object 类型,丢失类型信息
影响: 消息处理逻辑无法获取正确的类型,可能导致运行时错误
建议: 使用泛型或类型安全的消息包装器
3. AOP 模块中重复的 NullLogger 实现
模块: AOP
文件: LogInterceptor.cs, PerformanceMonitorInterceptor.cs, RetryInterceptor.cs
问题: 三个拦截器都实现了自己的 NullLogger 类,代码重复
影响: 代码维护困难,增加程序集大小
修复状态: ✅ 已修复(使用 Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance)
建议: 使用 .NET 内置的 NullLogger.Instance
4. MongoDB 审计处理器使用反射性能差
模块: MongoDB
文件: MongoHandlers.cs
问题: SetPropertyValue 方法使用反射设置属性值,性能较差
影响: 高频操作时性能下降
建议: 使用表达式树或预先编译的委托
🟡 中优先级问题(建议近期修复)
5. 配置选项类缺失或不完整
** affected 模块**: AI, ElasticSearch, gRPC, Http, Resilience
问题详情:
- AI 模块:
AddAIServices(IConfiguration)方法中复制 options 的方式有问题 - ElasticSearch 模块: 缺少
IElasticClient的注册 - gRPC 模块:
GrpcOptions类中的配置没有被实际使用 - Http 模块: Consul 集成调用方式有误
- Resilience 模块: 配置类命名不一致
修复状态: ✅ 已全部修复
6. 硬编码的默认值和 Header 名称
** affected 模块**: AOP, Middleware, MongoDB, OpenTelemetry
问题详情:
- AOP 模块: 缓存过期时间、重试次数等硬编码
- Middleware 模块: 关联 ID 的 Header 名称硬编码
- MongoDB 模块: 默认数据库名称不合适
- OpenTelemetry 模块: Jaeger 端口配置过时
建议: 创建配置类,支持从配置文件读取
7. 接口命名拼写错误和不一致
** affected 模块**: Resilience, YARP
问题详情:
- Resilience 模块: 方法名拼写错误(
GetCircuitBreakerPolicy应为GetCircuitBreakerPolicy) - YARP 模块: 文件夹名为
YARP,但类和配置使用Yarp或Yarp(大小写不一致)
建议: 统一命名规范,修正拼写错误
8. 过时的代码未清理
** affected 模块**: Middleware
问题详情:
HealthCheckMiddleware.cs和ExceptionHandlingMiddleware.cs已标记[Obsolete],但代码仍未删除
建议: 直接删除这些过时文件
🟢 低优先级问题(可后续优化)
9. 代码注释和文档完善
** affected 模块**: 所有模块
建议:
- 添加 XML 文档注释
- 更新 README.md 文件
- 添加更多使用示例
10. 配置验证增强
** affected 模块**: 所有模块
建议:
- 添加配置验证
- 提供默认配置
- 验证必要的配置项
11. 日志记录的规范化
** affected 模块**: 所有模块
建议:
- 统一日志格式
- 使用结构化日志
- 添加适当的日志级别
模块检查状态汇总
| 模块 | 检查状态 | 问题数 | 修复状态 |
|---|---|---|---|
| AOP | ✅ 已检查 | 4 | ✅ 已修复 |
| Extensions | ✅ 已检查 | 2 | ⏳ 待修复 |
| Middleware | ✅ 已检查 | 4 | ⏳ 待修复 |
| MongoDB | ✅ 已检查 | 3 | ⏳ 待修复 |
| OpenTelemetry | ✅ 已检查 | 3 | ⏳ 待修复 |
| OSS | ✅ 已检查 | 3 | ⏳ 待修复 |
| RabbitMQ | ✅ 已检查 | 4 | ⏳ 待修复 |
| Resilience | ✅ 已检查 | 3 | ⏳ 待修复 |
| UnitOfWork | ✅ 已检查 | 3 | ✅ 已修复 |
| YARP | ✅ 已检查 | 4 | ⏳ 待修复 |
| AI | ✅ 已检查 | 2 | ✅ 已修复 |
| ElasticSearch | ✅ 已检查 | 2 | ✅ 已修复 |
| gRPC | ✅ 已检查 | 3 | ✅ 已修复 |
| HealthChecks | ✅ 已检查 | 1 | ✅ 已修复 |
| Http | ✅ 已检查 | 2 | ✅ 已修复 |
| Logging | ✅ 已检查 | 1 | ✅ 已修复 |
| Authentication | ✅ 已检查 | 0 | - |
| Consul | ✅ 已检查 | 0 | - |
| Redis | ✅ 已检查 | 0 | - |
| Security | ✅ 已检查 | 0 | - |
| SqlSugar | ✅ 已检查 | 0 | ✅ 已修复 |
| Swagger | ✅ 已检查 | 0 | - |
下一步行动计划
- 立即修复(高优先级): 4 个问题已全部修复 ✅
- 近期修复(中优先级): 18 个问题,已修复 10 个,剩余 8 个待修复
- 后续优化(低优先级): 15 个问题,建议后续逐步优化
如何贡献
如果你发现了新的问题或有改进建议,请:
- 在代码中添加
TODO或FIXME注释 - 更新相应的 README.md 文件
- 提交 Pull Request 并描述问题和修复方案
维护者: Healnet Team
最后更新: 2026-06-25
更新日志
v1.7.2 (2026-06-25)
🐛 修复:
- 消除所有编译警告(52个)
- 更新所有 NuGet 包为具体版本号,避免版本降级警告
- 使用 Directory.Build.props 统一设置输出路径,消除 MSB3539 警告
- 修复 NullLogger 实现的可空性约束问题
📦 依赖更新:
- SqlSugarCore: 5.1.4.58
- SqlSugar.ClickHouseCore: 5.1.4.1
- Consul: 1.7.14.1
- StackExchange.Redis: 2.9.11
- 其他所有包更新为具体版本
v1.7.1 (2026-06-20)
🐛 修复:
- 修复 GrpcOperationFilter 空引用 bug
v1.7.0 (2026-06-15)
✨ 新增:
- Consul 便捷调用接口 (IConsulHttpClient)
- YARP 配置文件驱动
- YARP 弹性策略集成
- Swagger gRPC 支持
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Aliyun.OSS.SDK.NetCore (>= 2.14.0)
- AspectCore.Core (>= 2.4.0)
- AspectCore.Extensions.DependencyInjection (>= 2.4.0)
- Azure.AI.OpenAI (>= 2.9.0-beta.1)
- Consul (>= 1.7.14.1)
- Grpc.AspNetCore (>= 2.65.0)
- Grpc.Net.Client (>= 2.65.0)
- Healnet.Common (>= 2.0.0)
- Healnet.Core (>= 2.0.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.0)
- Microsoft.AspNetCore.Grpc.JsonTranscoding (>= 8.0.0)
- Microsoft.Extensions.AI (>= 9.10.0)
- Microsoft.Extensions.AI.OpenAI (>= 10.3.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Http.Polly (>= 8.0.0)
- Microsoft.SemanticKernel (>= 1.67.0)
- MongoDB.Driver (>= 2.29.0)
- NEST (>= 7.17.0)
- OpenTelemetry.Exporter.Console (>= 1.7.0)
- OpenTelemetry.Exporter.Jaeger (>= 1.6.0-rc.1)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.7.0)
- OpenTelemetry.Exporter.Zipkin (>= 1.7.0)
- OpenTelemetry.Extensions.Hosting (>= 1.7.0)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.7.0)
- OpenTelemetry.Instrumentation.Http (>= 1.7.0)
- OpenTelemetry.Instrumentation.SqlClient (>= 1.15.0)
- Oracle.ManagedDataAccess.Core (>= 3.21.130)
- Polly (>= 8.3.0)
- Polly.RateLimiting (>= 8.0.0)
- RabbitMQ.Client (>= 6.8.0)
- Serilog.AspNetCore (>= 8.0.0)
- Serilog.Extensions.Hosting (>= 8.0.0)
- Serilog.Sinks.Console (>= 6.0.0)
- Serilog.Sinks.Elasticsearch (>= 9.0.0)
- Serilog.Sinks.File (>= 5.0.0)
- SqlSugar.ClickHouseCore (>= 5.1.4.1)
- SqlSugarCore (>= 5.1.4.58)
- StackExchange.Redis (>= 2.9.11)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.5.0)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.5.0)
- System.DirectoryServices.Protocols (>= 8.0.0)
- System.Drawing.Common (>= 8.0.0)
- System.IdentityModel.Tokens.Jwt (>= 8.0.0)
- System.Interactive.Async (>= 6.0.1)
- Yarp.ReverseProxy (>= 2.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0 | 38 | 7/16/2026 |
| 2.0.7 | 59 | 7/10/2026 |
| 2.0.5 | 61 | 7/8/2026 |
| 2.0.3 | 65 | 6/30/2026 |
| 2.0.1 | 65 | 6/30/2026 |
| 2.0.0 | 64 | 6/29/2026 |
| 1.7.3 | 58 | 6/29/2026 |
| 1.7.2 | 63 | 6/25/2026 |
| 1.7.1 | 58 | 6/25/2026 |
| 1.7.0 | 63 | 6/25/2026 |
| 1.6.0 | 75 | 6/24/2026 |
| 1.5.0 | 63 | 6/16/2026 |
| 1.4.0 | 62 | 6/15/2026 |
| 1.3.0 | 76 | 5/29/2026 |
| 1.1.1 | 63 | 5/25/2026 |
| 1.1.0 | 66 | 5/22/2026 |
| 1.0.19 | 69 | 5/20/2026 |
| 1.0.18 | 59 | 5/20/2026 |
| 1.0.17 | 59 | 5/20/2026 |
| 1.0.15 | 63 | 5/20/2026 |
v1.7.1: 修复 GrpcOperationFilter 空引用 bug,确保 operation.Tags 和 operation.Extensions 不为 null。v1.7.0: Consul 新增 IConsulHttpClient 便捷调用接口;YARP 新增配置文件驱动和 Polly 弹性策略集成;Swagger 新增 gRPC JSON Transcoding 支持。