ProtoGenNet 0.0.1.5
See the version list below for details.
dotnet add package ProtoGenNet --version 0.0.1.5
NuGet\Install-Package ProtoGenNet -Version 0.0.1.5
<PackageReference Include="ProtoGenNet" Version="0.0.1.5" />
<PackageVersion Include="ProtoGenNet" Version="0.0.1.5" />
<PackageReference Include="ProtoGenNet" />
paket add ProtoGenNet --version 0.0.1.5
#r "nuget: ProtoGenNet, 0.0.1.5"
#:package ProtoGenNet@0.0.1.5
#addin nuget:?package=ProtoGenNet&version=0.0.1.5
#tool nuget:?package=ProtoGenNet&version=0.0.1.5
ProtoGen - C# to Protocol Buffer Generator
ProtoGenNet is a C# console application that automatically generates .proto files from C# interfaces using reflection and provides dynamic proxy support for transparent gRPC method invocation.
Features
- Attribute-Based Generation: Uses
[Browsable(true)]attributes to control what gets included in the generated.protofile - Automatic Type Mapping: Maps C# types (primitives, classes, structs, enums, collections) to Protocol Buffer types
- Castle DynamicProxy Integration: Creates dynamic proxies that transparently route method calls to gRPC clients
- AutoMapper Support: Automatically maps between C# DTOs and Protobuf-generated messages
- Reflection-Based: No manual
.protofile authoring required
How It Works
1. Proto Generation from C# Interfaces
Classes and interfaces decorated with [Browsable(true)] are used as service definitions. Only virtual methods with [Browsable(true)] are included as RPC methods.
[Browsable(true)]
public interface ISampleService
{
[Browsable(true)]
string GetGreeting(string name);
[Browsable(true)]
UserProfile GetUserProfile(string userId);
// This method is NOT included (no [Browsable(true)])
void InternalMethod();
}
2. Generated Proto Output
The above interface generates:
syntax = "proto3";
package sample;
service ISampleService {
rpc GetGreeting (GetGreetingRequest) returns (GetGreetingResponse) {}
rpc GetUserProfile (GetUserProfileRequest) returns (UserProfile) {}
}
message GetGreetingRequest {
string name = 1;
}
message GetGreetingResponse {
string value = 1;
}
message GetUserProfileRequest {
string userId = 1;
}
message UserProfile {
PersonInfo person = 1;
Address address = 2;
repeated string interests = 3;
}
3. Type Mapping
ProtoGen automatically maps C# types to Protocol Buffer types:
| C# Type | Proto Type |
|---|---|
bool |
bool |
int, short, byte, sbyte |
int32 |
long |
int64 |
uint, ushort |
uint32 |
ulong |
uint64 |
float |
float |
double, decimal |
double |
string |
string |
byte[] |
bytes |
enum |
enum (generated) |
List<T>, T[] |
repeated T |
| Classes/Structs | message (generated) |
void, Task |
google.protobuf.Empty |
4. Dynamic Proxy Usage
Use Castle DynamicProxy to create transparent proxies that route calls to gRPC:
// Setup
var mapperConfig = AutoMapperConfiguration.CreateWithAutoMapping(Assembly.GetExecutingAssembly());
var proxyGenerator = new ProxyGenerator(mapperConfig.Mapper);
// Create gRPC client (from generated code)
var channel = new Channel("localhost:50051", ChannelCredentials.Insecure);
var grpcClient = new SampleService.SampleServiceClient(channel);
// Create proxy
var proxy = proxyGenerator.CreateProxy<ISampleService>(grpcClient);
// Use it like a local interface!
var result = proxy.GetGreeting("World");
var profile = proxy.GetUserProfile("user123");
5. AutoMapper Integration
AutoMapper automatically handles mapping between your C# DTOs and Protobuf-generated messages:
- Complex objects with nested properties
- Collections (
List<T>↔repeatedfields) - Structs and classes
- Property name matching (case-insensitive)
Project Structure
ProtoGen/
├── ProtoGen.csproj # Project file with NuGet dependencies
├── Program.cs # Demo application
├── Generator/
│ ├── ProtoGenerator.cs # Main proto file generator
│ ├── TypeMapper.cs # C# to Protobuf type mapping
│ └── ProtoFileWriter.cs # (future: file writing utilities)
├── Proxy/
│ ├── ProxyGenerator.cs # Castle DynamicProxy wrapper
│ ├── GrpcInterceptor.cs # Method call interceptor
│ └── AutoMapperConfiguration.cs # AutoMapper setup
└── Samples/
├── ISampleService.cs # Example service interface
└── SampleModels.cs # Example data models
Dependencies
- AutoMapper (13.0.1) - DTO mapping
- Castle.Core (5.1.1) - Dynamic proxy generation
- Google.Protobuf (3.32.1) - Protobuf runtime
- Grpc.Core (2.46.6) - gRPC runtime
- Grpc.Tools (2.72.0) - Build-time proto compilation
Usage
Running the Demo
cd ProtoGen
dotnet run
This will:
- Generate a
.protofile fromISampleService - Save it to
../Protos/sample_service.proto - Display the generated content
- Demonstrate AutoMapper and ProxyGenerator setup
Generating Proto from Your Own Interface
var generator = new ProtoGen.Generator.ProtoGenerator
{
PackageName = "myapp",
ServiceName = "MyService"
};
var protoContent = generator.GenerateProto(typeof(IMyService));
File.WriteAllText("my_service.proto", protoContent);
Complete Workflow
- Define Interface: Create C# interface with
[Browsable(true)]attributes - Generate Proto: Run ProtoGen to create
.protofile - Compile Proto: Use
Grpc.Toolsto generate C# gRPC client/server code - Implement Server: Create gRPC server implementing the service
- Create Proxy: Use ProxyGenerator to create transparent client proxy
- Call Methods: Use the proxy like a local interface
Key Design Decisions
Why [Browsable(true)]?
- Existing attribute from
System.ComponentModel - Semantic meaning: "expose this to external systems"
- No custom attributes needed
- Works well with PropertyGrid and other reflection tools
Why Virtual Methods Only?
- Ensures interface compatibility
- Prevents generation of non-overrideable methods
- Aligns with proxy pattern requirements
- Forces explicit opt-in for each method
Why Wrapper Messages for Primitives?
- gRPC best practices recommend message types for requests/responses
- Allows future extensibility (add fields without breaking changes)
- Avoids proto3 limitations with primitive types
- Consistent patterns across all RPC methods
Limitations
- Only supports
[Browsable(true)]for filtering - No support for client/server streaming (yet)
- No support for bidirectional streaming (yet)
- Decimal types map to double (proto3 limitation)
- No circular reference detection (can cause stack overflow)
Future Enhancements
- Support for streaming RPC patterns
- Custom attribute support beyond
[Browsable] - Circular reference detection
- Source generator version (compile-time)
- Integration with ASP.NET Core gRPC
- Support for proto options and annotations
- Validation rule generation
Example Output
See sample_service.proto for example generated output from ISampleService.
License
Part of the FlexUI gRPC examples project.
| Product | Versions 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. |
This package has no dependencies.
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 |
|---|---|---|
| 0.0.1.12 | 723 | 12/3/2025 |
| 0.0.1.11 | 689 | 12/3/2025 |
| 0.0.1.10 | 138 | 11/29/2025 |
| 0.0.1.9 | 194 | 11/28/2025 |
| 0.0.1.8 | 199 | 11/27/2025 |
| 0.0.1.7 | 207 | 11/25/2025 |
| 0.0.1.6 | 209 | 11/25/2025 |
| 0.0.1.5 | 423 | 11/20/2025 |
| 0.0.1.4 | 423 | 11/20/2025 |
| 0.0.1.3 | 420 | 11/19/2025 |
| 0.0.1.2 | 418 | 11/19/2025 |
| 0.0.1.1 | 426 | 11/19/2025 |