Skip to content

Orleans source generation

Orleans generates grain proxies, method dispatch code, serializers, and copiers at build time. There is no runtime or initialization-time code generation workflow for application code.

Use the package matching the project role:

These packages include the source generator and analyzers.

The generator discovers grain interfaces and implementations from their Orleans base interfaces. It reports build diagnostics for unsupported signatures, inaccessible types, multiple cancellation token parameters, and other contract errors.

Supported grain method return types are Task, Task<T>, ValueTask, and ValueTask<T>. The generator emits strongly typed references and invocation classes for those methods.

Mark application data crossing grain boundaries or stored by Orleans with GenerateSerializerAttribute. Give serialized members stable field IDs:

[GenerateSerializer]
public sealed class PurchaseOrder
{
[Id(0)]
public required string OrderId { get; init; }
[Id(1)]
public decimal Total { get; init; }
}

IDs are part of the wire and storage contract. Don’t reuse or renumber them after deployment. Use AliasAttribute when a stable serialized type alias is required independently of the CLR name.

Enable the Hot Reload generation shape in development builds:

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<OrleansHotReload>true</OrleansHotReload>
</PropertyGroup>

The generator gives serializer and copier fields stable identities and resolves newly added concrete codec and copier dependencies when an existing generated instance first uses them. A running application can therefore apply supported .NET Hot Reload updates which add strongly typed [Id] members to [GenerateSerializer] classes and records, including members whose concrete serializable type is added in the same update.

Keep each [Id] value stable and unique. Additive member updates preserve the existing wire contract. Changes to existing member types, IDs, type hierarchy, generic shape, grain interfaces, and generated invokable types follow the corresponding .NET Hot Reload and Orleans contract compatibility requirements. A restart rebuilds the serializer manifest after updates which introduce new types through polymorphic declarations such as object or interfaces, or through container element types.

When OrleansHotReload is unset or false, the generator emits readonly fields with eager initialization for normal application builds.

When a project must generate serializers for accessible types declared elsewhere, use GenerateCodeForDeclaringAssemblyAttribute:

[assembly: GenerateCodeForDeclaringAssembly(
typeof(ExternalContract))]

Prefer owning serialization annotations with the type whenever possible. Generating for external declaring assemblies broadens the compatibility surface and can increase build output.

For end-to-end interop examples, see the Orleans F# sample and Orleans Visual Basic sample.

Treat Orleans analyzer and generator diagnostics as contract errors. Orleans marks generated implementation types with EditorBrowsable(Never) for editors which honor this metadata. Generated files retain their source locations for diagnostics and debugging, and remain available through compiler-generated-file tooling and direct definition navigation to generated symbols.

Roslyn honors type-level EditorBrowsable for type completion from referenced assemblies. Member completion, same-assembly type completion, and implementation searches include generated symbols while their implementation trees participate in the compilation.

The generator registers serializers, copiers, activators, proxies, invocation helpers, runtime metadata, and serializer-context registration bodies with Roslyn’s RegisterImplementationSourceOutput. Minimal serializer-context declarations use regular source output to complete authored partial types for editor type checking, including consumers of projects whose implementation outputs are omitted. Hosts choose whether to include implementation outputs in their compilations; ordinary builds include the complete generated implementation. Context-shape and supported-contract diagnostics use regular output. Diagnostics which require a producer’s generated codec or copier metadata accompany implementation output.

XML documentation contains authored API comments. The documentation site’s API reference filters generated implementation types and members using their generated-code attributes, preserving authored partial types such as serializer contexts.

The optional Orleans contract compatibility analyzer records grain RPC identities and signatures in OrleansContracts.txt so contract drift can be reviewed before a rolling upgrade.

Libraries which define custom grain-call return types can extend the generated proxy and invokable request model. See Customize Orleans serialization code generation.

For serialization rules and version tolerance, see Orleans serialization.