AvroSourceGenerator 0.1.1
See the version list below for details.
dotnet add package AvroSourceGenerator --version 0.1.1
NuGet\Install-Package AvroSourceGenerator -Version 0.1.1
<PackageReference Include="AvroSourceGenerator" Version="0.1.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="AvroSourceGenerator" Version="0.1.1" />
<PackageReference Include="AvroSourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add AvroSourceGenerator --version 0.1.1
#r "nuget: AvroSourceGenerator, 0.1.1"
#:package AvroSourceGenerator@0.1.1
#addin nuget:?package=AvroSourceGenerator&version=0.1.1
#tool nuget:?package=AvroSourceGenerator&version=0.1.1
Avro Source Generator
Avro Source Generator is a .NET source generator that generates C# code from Avro schemas and is compatible with Apache Avro.
It produces models that use modern C# features, such as nullable reference types, init-only properties, required properties, and more.
Prerequisites
- .NET SDK 8.0 or later
Usage
To use the Avro Source Generator in your project, add a reference to the AvroSourceGenerator
package in your .csproj
file:
dotnet add package AvroSourceGenerator
You can mark the AvroSourceGenerator
package as PrivateAssets="all"
to prevent projects referencing yours from getting a reference to it. Additionally, use ExcludeAssets="runtime"
to ensure that AvroSourceGenerator.Attributes
is not copied to the build output, since it is not required at runtime.
<PackageReference Include="AvroSourceGenerator" Version="*" PrivateAssets="all" ExcludeAssets="runtime" />
Then, configure the .csproj
to include Avro schema files as AdditionalFiles
.
<ItemGroup>
<AdditionalFiles Include="schemas/*.avsc" />
</ItemGroup>
Add the schema file to the schemas
folder in your project.
schemas/user.avsc
{
"type": "record",
"name": "User",
"namespace": "example",
"fields": [
{
"name": "Name",
"type": "string"
},
{
"name": "Email",
"type": [
"null",
"string"
]
},
{
"name": "CreatedAt",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
}
]
}
Schema files must have a .avsc
extension.
This will generate the C# files containing the types defined in the Avro schema.
Here is an example of a generated class for the User
schema defined above:
// <auto-generated/>
#pragma warning disable CS8618, CS8633, CS8714, CS8775, CS8981
#nullable enable
namespace example
{
[global::System.CodeDom.Compiler.GeneratedCode("AvroSourceGenerator", "1.0.0.0")]
public partial record User : global::Avro.Specific.ISpecificRecord
{
public required string Name { get; init; }
public string? Email { get; init; }
public required global::System.DateTime CreatedAt { get; init; }
public global::Avro.Schema Schema { get => User._SCHEMA; }
public static readonly global::Avro.Schema _SCHEMA = global::Avro.Schema.Parse("""
{
"type": "record",
"name": "User",
"namespace": "example",
"fields": [
{
"name": "Name",
"type": "string"
},
{
"name": "Email",
"type": [
"null",
"string"
]
},
{
"name": "CreatedAt",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
}
]
}
""");
public object? Get(int fieldPos)
{
switch (fieldPos)
{
case 0: return this.Name;
case 1: return this.Email;
case 2: return this.CreatedAt;
default: throw new global::Avro.AvroRuntimeException($"Bad index {fieldPos} in Get()");
}
}
public void Put(int fieldPos, object? fieldValue)
{
switch (fieldPos)
{
case 0:
Set_Name(this, (string)fieldValue!); break;
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "set_Name")]
extern static void Set_Name(User obj, string value);
case 1:
Set_Email(this, fieldValue! is null ? null : (string)fieldValue!); break;
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "set_Email")]
extern static void Set_Email(User obj, string? value);
case 2:
Set_CreatedAt(this, (global::System.DateTime)fieldValue!); break;
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "set_CreatedAt")]
extern static void Set_CreatedAt(User obj, global::System.DateTime value);
default:
throw new global::Avro.AvroRuntimeException($"Bad index {fieldPos} in Put()");
}
}
}
}
#nullable restore
#pragma warning restore CS8618, CS8633, CS8714, CS8775
Extending generated code
Generated types are declared as partial
, enabling you to extend them by providing additional partial definitions.
Example for the User
type generated above.
namespace example;
public partial record User
{
public override string ToString() => Name;
}
Access modifier
By default, all generated types are declared as public
.
To change the access modifier for all generated types, include the AvroSourceGeneratorAccessModifier
property in your .csproj
file.
<PropertyGroup>
<AvroSourceGeneratorAccessModifier>internal</AvroSourceGeneratorAccessModifier>
</PropertyGroup>
Supported values are public
(default) and internal
.
To change the access modifier of just one type, declare a partial definition for it using the desired access modifier, and annotate it with the Avro
attribute.
using AvroSourceGenerator;
namespace example;
[Avro]
internal partial record User;
Records
By default, the generator uses record
declarations for generated types whenever possible.
To modify this behavior for all generated types, include the AvroSourceGeneratorRecordDeclaration
property in your .csproj
file.
<PropertyGroup>
<AvroSourceGeneratorRecordDeclaration>class</AvroSourceGeneratorRecordDeclaration>
</PropertyGroup>
Supported values are record
(default) and class
.
To change the declaration of just one type, declare a partial definition for it using the desired record
or class
keyword, and annotate it with the Avro
attribute.
using AvroSourceGenerator;
namespace example;
[Avro]
public partial class User;
This feature is only applicable to Avro record
schemas. Note that fixed
and error
schemas will always generate standard classes, as they are required to inherit from non-record types.
Language features
By default, the generated code utilizes the latest C# language features supported by the consuming project.
However, you can specify the C# language features to be used in the generated code to ensure compatibility with older versions of C#. For instance, setting LanguageFeatures.CSharp7_3
will restrict the generated code to features available in C# 7.3, such as excluding nullable reference types and records.
To configure language features for all generated code, include the AvroSourceGeneratorLanguageFeatures
property in your .csproj
file.
<PropertyGroup>
<AvroSourceGeneratorLanguageFeatures>CSharp7_3</AvroSourceGeneratorLanguageFeatures>
</PropertyGroup>
Supported values include all flags defined in the LanguageFeatures
enum.
Parsing is case-insensitive and follows the default rules for flags (using Enum.Parse
).
To change used features for just one type, declare a partial definition for it, and annotate it with the Avro
attribute, specifying a LanguageFeatures
argument.
using AvroSourceGenerator;
namespace example;
[Avro(LanguageFeatures = LanguageFeatures.CSharp7_3)]
public partial record User;
It is also possible to enable or disable specific features.
Example for using the latest features but excluding required properties:
using AvroSourceGenerator;
namespace example;
[Avro(LanguageFeatures = LanguageFeatures.Latest & ~LanguageFeatures.RequiredProperties)]
public partial record User;
Limitations
In C#, enum
types cannot be declared as partial
, so it's not possible to configure code generation for just a single enum
type.
A possible workaround for this is to wrap the enum
schema in a record
schema.
<details> <summary> Enum Wrapper Example </summary>
Before
Suit.avsc
{
"type": "enum",
"name": "Suit",
"namespace": "example",
"symbols": [
"Hearts",
"Diamonds",
"Clubs",
"Spades"
]
}
Suit.Avro.g.cs
// <auto-generated/>
namespace example
{
[global::System.CodeDom.Compiler.GeneratedCode("AvroSourceGenerator", "1.0.0.0")]
public enum Suit
{
Hearts,
Diamonds,
Clubs,
Spades,
}
}
After
SuitWrapper.avsc
{
"type": "record",
"name": "SuitWrapper",
"namespace": "example",
"fields": [
{
"name": "WrapperField",
"type": {
"type": "enum",
"name": "Suit",
"namespace": "example",
"symbols": [
"Hearts",
"Diamonds",
"Clubs",
"Spades"
]
}
}
]
}
SuitWrapper.cs
using AvroSourceGenerator;
namespace example;
[Avro]
internal partial record SuitWrapper;
Suit.Avro.g.cs
// <auto-generated/>
namespace example
{
[global::System.CodeDom.Compiler.GeneratedCode("AvroSourceGenerator", "1.0.0.0")]
internal enum Suit
{
Hearts,
Diamonds,
Clubs,
Spades,
}
}
</details>
Contributing
Contributions are welcome! If you have any ideas, suggestions, or bug reports, please open an issue or submit a pull request.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Apache.Avro (>= 1.12.0)
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.2.2 | 136 | 7/13/2025 |
0.2.1 | 69 | 7/4/2025 |
0.2.1-preview2 | 138 | 6/23/2025 |
0.2.1-preview1 | 310 | 6/7/2025 |
0.2.0 | 11,924 | 5/16/2025 |
0.2.0-preview.2 | 245 | 5/15/2025 |
0.2.0-preview.1 | 128 | 5/7/2025 |
0.1.1 | 260 | 4/23/2025 |
0.1.1-preview.1 | 165 | 4/17/2025 |
0.1.0 | 173 | 4/10/2025 |
0.1.0-preview.6 | 140 | 4/8/2025 |