C# GRPC是否可直接引用现有类无需在.proto中重复定义
问题解答
常规proto-first工作流的要求
- 默认情况下,如果你使用gRPC官方推荐的*契约优先(proto-first)*工作流,是需要在
.proto文件中定义对应message结构的。原因是该模式下,gRPC的序列化、服务接口、客户端/服务端存根代码都基于.proto文件自动生成,.proto是跨语言的通用契约定义,和具体开发语言的类定义无关。 - 这种模式下如果要避免手动重复编写字段,你可以通过T4模板、自定义代码生成工具,直接从现有C#公共类自动生成对应
.proto结构,减少重复劳作。
无需定义.proto的实现方案
如果你整个解决方案都是C#技术栈,不需要对外提供多语言gRPC调用支持,可以使用**Code-First(代码优先)**模式实现gRPC,直接复用现有Car类,无需编写.proto文件,操作步骤如下:
- 安装相关NuGet包:
- 服务端项目安装
protobuf-net.Grpc.AspNetCore - 客户端项目安装
protobuf-net.Grpc.Client - 公共类所在的Core项目安装
protobuf-net
- 服务端项目安装
- 给现有
Car类添加序列化标记,对应proto中的字段编号:using ProtoBuf; [ProtoContract] public class Car { [ProtoMember(1)] public int Id { get; set; } [ProtoMember(2)] public string Brand { get; set; } [ProtoMember(3)] public string? Type {get; set;} } - 直接用C#接口定义gRPC服务契约,无需编写.proto:
using ProtoBuf.Grpc; using System.ServiceModel; using System.Threading.Tasks; [ServiceContract] public interface ICarService { [OperationContract] Task<Car> GetCarAsync(int carId, CallContext context = default); } - 服务端实现该接口并注册服务,客户端直接通过该接口调用即可,全程不需要额外定义proto结构,直接复用现有公共类。
注意事项
- Code-First模式下如果后续需要提供多语言调用支持,你可以基于现有标记好的C#类,自动生成对应
.proto契约提供给其他语言的调用方。 - 序列化标记的字段编号需要全局唯一且不可随意修改,和proto-first模式下的字段编号规则完全一致。
内容的提问来源于stack exchange,提问作者mortenstarck
相关产品推荐
相关产品推荐

