Codify.GrpcCodeFirstContractGuard 1.0.2

dotnet add package Codify.GrpcCodeFirstContractGuard --version 1.0.2
                    
NuGet\Install-Package Codify.GrpcCodeFirstContractGuard -Version 1.0.2
                    
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="Codify.GrpcCodeFirstContractGuard" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Codify.GrpcCodeFirstContractGuard" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Codify.GrpcCodeFirstContractGuard" />
                    
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 Codify.GrpcCodeFirstContractGuard --version 1.0.2
                    
#r "nuget: Codify.GrpcCodeFirstContractGuard, 1.0.2"
                    
#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 Codify.GrpcCodeFirstContractGuard@1.0.2
                    
#: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=Codify.GrpcCodeFirstContractGuard&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Codify.GrpcCodeFirstContractGuard&version=1.0.2
                    
Install as a Cake Tool

GRPC Code-First Contract Guard

Schema validation for gRPC Code-First services in .NET. Generates .proto schema files from your code-first service interfaces and detects backwards-incompatible changes before they reach production.

Code-first gRPC uses .NET types to define service and message contracts and is a very convenient choice when your entire ecosystem uses .NET. Instead of the schema being persisted in a .proto file, the schema is defined in the .NET types. This is a great way to define the schema as it allows for easy updates and refactoring via C# tooling. You can also define your validation with System.ComponentModel.DataAnnotations and validate with GrpcCodeFirstDataAnnotations.

However, when refactoring code / modifying gRPC models it can be difficult to guarantee that the schema is still backwards compatible. It is not always obvious if the schema has changed in a way that is not backwards compatible with existing clients. Your unit tests will be using the latest code-first models, so they'll pass even if you make a breaking schema change. This can lead to breaking changes being merged and deployed without anyone realizing the impact until clients start breaking in production.

Proto schema generation to the rescue — a handy feature of gRPC schema generation is that it can generate a .proto file from the .NET types. This package persists those schemas and compares them on each test run, surfacing any differences so you can make an informed decision about whether the change is safe.

For more background, see Automatic gRPC Schema Validation.

Packages

Package Description
Codify.GrpcCodeFirstContractGuard Generates and validates .proto schemas from code-first gRPC service interfaces

Getting Started

  1. Open your gRPC test project and install the NuGet package:
dotnet add package Codify.GrpcCodeFirstContractGuard
  1. Add a test class called ProtoContractGuardTest (or similar) to your test project. This class will contain the tests for generating the baseline schema and verifying it.

  2. Add a test to generate the baseline .proto schema files. Mark it with Skip = "Run manually to regenerate baseline" or for NUnit [Explicit] so it doesn't run automatically — only run it manually when you need to create or update the baseline.

  3. Add a test to verify that the schema hasn't changed. This test runs on every build and will fail if the schema has drifted:

public class ProtoContractGuardTest
{
    [Fact(Skip = "Run manually to regenerate baseline")] 
    public void GenerateProtoSchema()
    {
        var generatedFiles = ProtoContractGuard.GenerateBaselineFiles(
        [
            // One of the contract interfaces from each namespace. The rest will be discovered.
            typeof(IGreeterCodeFirst) 
        ]);

        // Assert that the expected number of files were generated
        generatedFiles.Should().NotBeEmpty("Baseline files should be generated");
    }

    [Fact]
    public void VerifyProtobufSchema()
    {
        var schemaDifferences = ProtoContractGuard.CompareCurrentToBaseline(
        [
            // One of the contract interfaces from each namespace. The rest will be discovered.
            typeof(IGreeterCodeFirst)
        ]);

        // Assert that there are no differences in the schema
        schemaDifferences.Should().BeNull("Schema differences should be empty for stable protobuf schemas");
    }
}
  1. When you run the GenerateProtoSchema test, it will create folder structure like this in your test project:
TestProject/
    ProtoContractGuardTest.cs
    ProtoContractGuard/
        IGreeterCodeFirst.proto
        IGreeterCodeFirstV2.proto
  1. When the VerifyProtobufSchema test is run, it will compare the current schema against the baseline. If a schema change is detected, the test will fail with a list of differences. The differences include the line number, change type, and the text of the line. For example:
[IGreeterCodeFirst.proto] ProtoContractGuard detected differences for IGreeterCodeFirst
  -    string FirstName = 1;
 6+    string Name = 1;
  -    string Infomation = 1;
 8+    string Info = 1;
  -    rpc SayHowdy (HelloCodeFirstRequest) returns (HelloCodeFirstResponse);
22+    rpc SayHello (HelloCodeFirstRequest) returns (HelloCodeFirstResponse);
[IGreeterCodeFirstV2.proto] ProtoContractGuard issue: No baseline found. Run GenerateBaselineFiles to create baseline for IGreeterCodeFirstV2.

If the schema change is intentional, regenerate the baseline files by running GenerateBaselineFiles again and commit the updated .proto files. If not, then review your changes and fix any unintended breaking changes before committing.

How It Works

  1. GenerateGenerateBaselineFiles uses protobuf-net.Grpc to generate .proto schemas from your code-first service interfaces and writes them to disk.
  2. VerifyCompareCurrentToBaseline generates the current schema in memory and compares it against the persisted .proto files using an inline diff.
  3. Review — Any differences are returned as a list of diff lines, making it easy to assert in your tests and review in CI output.

A test failure indicates a schema change, but not all changes break compatibility. Each should be manually reviewed.

License

See license for details.

Product 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. 
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.0.2 74 6/9/2026
1.0.1 83 6/5/2026
1.0.0 84 6/5/2026