SyZero.DynamicGrpc 1.1.4-dev.1

This is a prerelease version of SyZero.DynamicGrpc.
There is a newer version of this package available.
See the version list below for details.
dotnet add package SyZero.DynamicGrpc --version 1.1.4-dev.1
                    
NuGet\Install-Package SyZero.DynamicGrpc -Version 1.1.4-dev.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SyZero.DynamicGrpc" Version="1.1.4-dev.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SyZero.DynamicGrpc" Version="1.1.4-dev.1" />
                    
Directory.Packages.props
<PackageReference Include="SyZero.DynamicGrpc" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SyZero.DynamicGrpc --version 1.1.4-dev.1
                    
#r "nuget: SyZero.DynamicGrpc, 1.1.4-dev.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SyZero.DynamicGrpc@1.1.4-dev.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SyZero.DynamicGrpc&version=1.1.4-dev.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=SyZero.DynamicGrpc&version=1.1.4-dev.1&prerelease
                    
Install as a Cake Tool

SyZero.DynamicGrpc

动态 gRPC 服务生成框架,基于 protobuf-net.Grpc 实现 Code-First gRPC,无需 .proto 文件。

📦 安装

dotnet add package SyZero.DynamicGrpc

✨ 特性

  • 🎯 Code-First - 无需 .proto 文件,直接从 C# 接口生成 gRPC 服务
  • 🚀 自动服务发现 - 基于 IDynamicApi 接口和特性标记自动发现 gRPC 服务
  • 高性能 - 使用 Protobuf 二进制序列化,性能优异
  • 🔧 灵活配置 - 支持自定义消息大小限制、详细错误等
  • 🎯 无侵入设计 - 与现有 SyZero 框架无缝集成

🚀 快速开始(Code-First 模式)

1. 定义数据契约

直接使用普通 POCO 类:

public class HelloRequest
{
    public string Name { get; set; }
}

public class HelloReply
{
    public string Message { get; set; }
}

2. 定义服务接口

using System.Threading.Tasks;
using SyZero.Application.Service;
using SyZero.Application.Attributes;

[DynamicApi]  // 标记在接口层,自动注册为 gRPC 服务
public interface IGreeterService : IApplicationService, IDynamicApi
{
    Task<HelloReply> SayHello(HelloRequest request);
    
    Task<HelloReply> SayGoodbye(HelloRequest request);
}

3. 实现服务

public class GreeterService : IGreeterService
{
    public Task<HelloReply> SayHello(HelloRequest request)
    {
        return Task.FromResult(new HelloReply
        {
            Message = $"Hello, {request.Name}!"
        });
    }

    public Task<HelloReply> SayGoodbye(HelloRequest request)
    {
        return Task.FromResult(new HelloReply
        {
            Message = $"Goodbye, {request.Name}!"
        });
    }
}

4. 配置服务端

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// 添加 Dynamic gRPC 服务
builder.Services.AddDynamicGrpc(options =>
{
    options.MaxReceiveMessageSize = 10 * 1024 * 1024; // 10MB
    options.MaxSendMessageSize = 10 * 1024 * 1024;    // 10MB
    options.EnableDetailedErrors = builder.Environment.IsDevelopment();
});

var app = builder.Build();

// 映射 gRPC 服务端点
app.MapDynamicGrpcServices();

app.Run();

5. 客户端调用

using Grpc.Net.Client;
using ProtoBuf.Grpc.Client;

// 创建通道
using var channel = GrpcChannel.ForAddress("https://localhost:5001");

// 创建客户端(Code-First 方式)
var client = channel.CreateGrpcService<IGreeterService>();

// 调用服务
var reply = await client.SayHello(new HelloRequest { Name = "World" });
Console.WriteLine(reply.Message); // Hello, World!

📖 配置选项

DynamicGrpcOptions

属性 类型 默认值 说明
RemoveServicePostfixes List<string> ["Service", "AppService", ...] 移除服务名称后缀
RemoveMethodPostfixes List<string> ["Async"] 移除方法名称后缀
MaxReceiveMessageSize int? null 最大接收消息大小(字节)
MaxSendMessageSize int? null 最大发送消息大小(字节)
EnableDetailedErrors bool false 启用详细错误信息

配置示例

builder.Services.AddDynamicGrpc(options =>
{
    // 消息大小限制
    options.MaxReceiveMessageSize = 20 * 1024 * 1024; // 20MB
    options.MaxSendMessageSize = 20 * 1024 * 1024;    // 20MB
    
    // 开发环境启用详细错误
    options.EnableDetailedErrors = builder.Environment.IsDevelopment();
});

配置文件配置

除了代码配置,也可以通过 appsettings.json 配置文件进行配置:

appsettings.json

{
  "DynamicGrpc": {
    "DefaultServicePrefix": "",
    "DefaultAreaName": "v1",
    "RemoveServicePostfixes": ["AppService", "ApplicationService", "Service", "GrpcService"],
    "RemoveMethodPostfixes": ["Async"],
    "MaxReceiveMessageSize": 10485760,
    "MaxSendMessageSize": 10485760,
    "EnableDetailedErrors": false
  }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// 方式一:从 IConfiguration 读取配置
builder.Services.AddDynamicGrpc(builder.Configuration);

// 方式二:从 IConfiguration 读取配置,并支持额外代码配置(代码配置会覆盖配置文件)
builder.Services.AddDynamicGrpc(builder.Configuration, options =>
{
    // 开发环境启用详细错误
    options.EnableDetailedErrors = builder.Environment.IsDevelopment();
});

// 方式三:指定自定义配置节名称
builder.Services.AddDynamicGrpc(builder.Configuration, "MyGrpcConfig");

// 方式四:从 AppConfig 读取配置(默认从 appsettings.json 的 "DynamicGrpc" 节点读取)
builder.Services.AddDynamicGrpc();

var app = builder.Build();

app.MapDynamicGrpcServices();

app.Run();

🏷️ 特性标记

说明:标记了 [DynamicApi] 的服务默认会自动注册为 gRPC 服务,无需额外标记。

NonGrpcServiceAttribute

排除某个 DynamicApi 服务不注册为 gRPC 服务:

[DynamicApi]
[NonGrpcService]  // 排除此服务不注册为 gRPC
public interface IInternalService : IApplicationService, IDynamicApi
{
    // 此服务只会注册为 HTTP API,不会注册为 gRPC 服务
}

NonGrpcMethodAttribute

排除某个方法不作为 gRPC 方法:

[DynamicApi]
public interface IMyService : IApplicationService, IDynamicApi
{
    Task<Response> NormalMethod(Request request);
    
    [NonGrpcMethod]
    void InternalMethod();  // 此方法不会暴露为 gRPC
}

🔄 流式传输支持

服务端流

public interface IStreamService : IDynamicApi
{
    IAsyncEnumerable<DataItem> GetDataStream(DataRequest request);
}

客户端流

public interface IStreamService : IDynamicApi
{
    Task<DataResponse> UploadData(IAsyncEnumerable<DataItem> items);
}

双向流

public interface IStreamService : IDynamicApi
{
    IAsyncEnumerable<DataItem> ProcessData(IAsyncEnumerable<DataItem> items);
}

🔗 与 DynamicWebApi 集成

同一服务同时支持 HTTP REST 和 gRPC:

[DynamicApi]  // 标记在接口层,同时暴露为 HTTP API 和 gRPC 服务
public interface IUserService : IApplicationService, IDynamicApi
{
    Task<UserResponse> GetUser(UserRequest request);
}

public class UserService : IUserService
{
    public Task<UserResponse> GetUser(UserRequest request)
    {
        return Task.FromResult(new UserResponse { Id = request.Id, Name = "John" });
    }
}
// Program.cs
builder.Services.AddDynamicWebApi();  // HTTP API
builder.Services.AddDynamicGrpc();    // gRPC

var app = builder.Build();

app.MapControllers();          // HTTP 端点
app.MapDynamicGrpcServices();  // gRPC 端点

🛡️ 拦截器

public class LoggingInterceptor : Interceptor
{
    private readonly ILogger<LoggingInterceptor> _logger;

    public LoggingInterceptor(ILogger<LoggingInterceptor> logger)
    {
        _logger = logger;
    }

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        _logger.LogInformation("gRPC: {Method}", context.Method);
        return await continuation(request, context);
    }
}

📄 许可证

MIT License - 详见 LICENSE

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.5-dev.1 28 1/29/2026
1.1.4 80 1/2/2026
1.1.4-dev.2 40 1/2/2026
1.1.4-dev.1 39 12/30/2025
1.1.3 83 12/30/2025
1.1.3-dev.6 41 12/30/2025