Generation emits plain C# source into a folder you choose. Unlike the TypeScript client, which is generated into node_modules, the C# client is regular source that compiles through your project's default glob. Commit it or gitignore it, your choice. Serialization, retries, and transport live in the Repost.Client runtime package; the generated code is data and types only.
The generator block#
A C# generator block sets three things the other languages don't need:
generator sdk {
language = "csharp"
output = "../Generated"
namespace = "Contoso.Events"
clientName = "RepostClient"
}| Field | What it owns |
|---|---|
output | The source root, resolved relative to the schema file. Repost owns this tree: it replaces its own files atomically and never touches anything else. |
namespace | The C# namespace for the generated models, the Webhooks tree, and the client. |
clientName | The generated client class name (RepostClient above). Pick a distinct name per schema when one project hosts more than one. |
What gets emitted#
| File | Purpose |
|---|---|
Client.cs | The client class and the Webhooks method tree, plus one input class per event (for example BookCreatedInput). |
Models.cs | Model classes and enums. Optional fields use Optional<T>; enums become C# enums. |
Descriptors.cs | The serialization descriptor set handed to the runtime at construction, declaring the descriptor-format version this package was emitted for. |
schema.repost | A verbatim copy of the schema this client was generated from. |
schemas.json | The JSON Schema catalog for your event types. |
.repost-client.json | The generation marker: format version, engine version, schema hash, and the file manifest. |
Models become classes, enums become C# enums, and optional fields use the tri-state Optional<T> container so absent, explicit null, and present are never conflated:
public enum Currency
{
Usd,
Eur,
}
public sealed partial class Author
{
public string Name { get; set; } = null!;
public Optional<string> Email { get; set; }
}The classes are partial, so you can add your own members in a separate file without touching the generated code.
Build-time generation with MSBuild#
For teams that would rather not commit generated source, the Repost.Client.MSBuild package runs the schema engine as an MSBuild task before compilation, the Grpc.Tools idiom:
<PackageReference Include="Repost.Client" Version="1.0.8" />
<PackageReference Include="Repost.Client.MSBuild" Version="1.0.8" PrivateAssets="all" />With a schema at repost/schema.repost, a normal dotnet build validates the schema, writes the client to Generated/, and compiles it. A second build with an unchanged schema and engine is a pure incremental skip, so design-time builds in Visual Studio no-op instantly. The package carries signed, platform-specific engine binaries and checksum-verifies the resolved binary before every run.
Regenerating and the CI drift check#
The repost CLI generates the identical tree from the same schema, so a teammate without the MSBuild package can regenerate too:
repost schema generaterepost schema migrate dev also regenerates as part of recording a migration, and repost schema generate --check verifies in CI that nothing has drifted without writing to your source tree.
The version handshake#
The generated Descriptors.cs declares descriptor format version 2, checked by the client constructor before any send:
- Generated code older than the runtime: the error tells you to re-run
repost schema generatewith the current engine. - Generated code newer than the runtime: the error tells you to upgrade
Repost.Client.
A real mismatch throws RepostDescriptorVersionException at construction, never silently at send time.