ToonNet.SourceGenerators
1.1.0
See the version list below for details.
dotnet add package ToonNet.SourceGenerators --version 1.1.0
NuGet\Install-Package ToonNet.SourceGenerators -Version 1.1.0
<PackageReference Include="ToonNet.SourceGenerators" Version="1.1.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="ToonNet.SourceGenerators" Version="1.1.0" />
<PackageReference Include="ToonNet.SourceGenerators"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add ToonNet.SourceGenerators --version 1.1.0
#r "nuget: ToonNet.SourceGenerators, 1.1.0"
#:package ToonNet.SourceGenerators@1.1.0
#addin nuget:?package=ToonNet.SourceGenerators&version=1.1.0
#tool nuget:?package=ToonNet.SourceGenerators&version=1.1.0
ToonNet.SourceGenerators
Compile-time code generation for zero-allocation TOON serialization
๐ฆ What is ToonNet.SourceGenerators?
ToonNet.SourceGenerators uses C# Source Generators to generate serialization code at compile-time:
- โ Zero Allocation - No runtime reflection or expression trees
- โ AOT Compatible - Works with Native AOT compilation
- โ Maximum Performance - Direct property access (no overhead)
- โ Type Safe - Compile-time errors for unsupported types
- โ Auto-Generated - No manual serialization code needed
Perfect for:
- โก Hot Paths - APIs with high-frequency serialization
- ๐ Performance Critical - Real-time systems, gaming, IoT
- ๐ฑ Native AOT - Self-contained executables
- ๐ฏ Zero Overhead - When every microsecond counts
๐ Quick Start
Installation
# Core package (required)
dotnet add package ToonNet.Core
# Source generators
dotnet add package ToonNet.SourceGenerators
Basic Usage
using ToonNet.Core.Serialization.Attributes;
// Mark class with [ToonSerializable]
[ToonSerializable]
public partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies { get; set; }
}
// Use the class
var person = new Person
{
Name = "Alice",
Age = 28,
Hobbies = new List<string> { "Reading", "Coding" }
};
// Serialize using ToonSerializer (runtime)
string toon = ToonSerializer.Serialize(person);
// Deserialize using ToonSerializer (runtime)
var personBack = ToonSerializer.Deserialize<Person>(toon);
// Alternative: Use generated static methods directly
var doc = Person.Serialize(person);
var restored = Person.Deserialize(doc);
Note: Source generator creates static Serialize and Deserialize methods at compile-time. You can use them directly or through ToonSerializer for zero-allocation performance.
๐ง How It Works
Source Generator Process
- Compile-Time Analysis - Analyzes [ToonSerializable] classes
- Code Generation - Generates serialization methods
- Zero Runtime Overhead - All work done at compile-time
Generated Code Example
Your Code:
[ToonSerializable]
public partial class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Generated Code (simplified):
// Source generator creates static Serialize and Deserialize methods
public partial class Product
{
/// <summary>
/// Serializes this instance to a TOON document (generated code).
/// </summary>
public static ToonDocument Serialize(
Product value,
ToonSerializerOptions? options = null)
{
// Direct property access with no reflection overhead
var obj = new ToonObject();
obj["Id"] = new ToonNumber(value.Id);
obj["Name"] = new ToonString(value.Name);
obj["Price"] = new ToonNumber((double)value.Price);
return new ToonDocument(obj);
}
/// <summary>
/// Deserializes a TOON document to an instance (generated code).
/// </summary>
public static Product Deserialize(
ToonDocument doc,
ToonSerializerOptions? options = null)
{
var obj = (ToonObject)doc.Root;
var result = new Product();
result.Id = (int)((ToonNumber)obj["Id"]).Value;
result.Name = ((ToonString)obj["Name"]).Value;
result.Price = (decimal)((ToonNumber)obj["Price"]).Value;
return result;
}
}
๐ Attributes
[ToonSerializable]
Marks a class for source generation:
[ToonSerializable]
public partial class MyClass
{
// Class must be partial
// Must have parameterless constructor (or primary constructor)
}
[ToonProperty]
Customizes property serialization:
[ToonSerializable]
public partial class Product
{
[ToonProperty("product_id")]
public int Id { get; set; }
public string Name { get; set; }
}
// Serializes as:
// product_id: 123
// Name: Laptop
[ToonIgnore]
Excludes properties from serialization:
[ToonSerializable]
public partial class User
{
public string Username { get; set; }
[ToonIgnore]
public string PasswordHash { get; set; } // Not serialized
}
โก Performance Comparison
Benchmark Results
BenchmarkDotNet v0.13.12, Windows 11
Intel Core i7-12700K, 1 CPU, 12 logical and 8 physical cores
.NET SDK 8.0.100
| Method | Mean | Allocated |
|-------------------------- |----------:|----------:|
| SourceGenerator_Serialize | 45.2 ns | - | โ Zero allocation!
| ExpressionTree_Serialize | 89.5 ns | 120 B |
| Reflection_Serialize | 4,250 ns | 856 B |
Source Generator is:
- 2x faster than Expression Trees
- 94x faster than Reflection
- Zero heap allocations (hot path)
When to Use Source Generators
โ Use Source Generators When:
- Hot path with high-frequency serialization
- AOT compilation required
- Zero-allocation is critical
- Startup performance matters
โ ๏ธ Use Runtime Serialization When:
- Types unknown at compile-time
- Dynamic type loading (plugins)
- Reflection-based scenarios
- Generic/flexible serialization
๐ฏ Real-World Examples
Example 1: High-Performance API
using ToonNet.Core.Serialization;
using ToonNet.Core.Serialization.Attributes;
[ToonSerializable]
public partial class ApiResponse
{
public int StatusCode { get; set; }
public string Message { get; set; }
public DateTime Timestamp { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
[HttpGet]
public IActionResult GetData()
{
var response = new ApiResponse
{
StatusCode = 200,
Message = "Success",
Timestamp = DateTime.UtcNow
};
// Zero-allocation serialization (source generator optimized)
var toon = ToonSerializer.Serialize(response);
return Content(toon, "application/toon");
}
}
Example 2: Gaming/Real-Time Systems
using ToonNet.Core.Serialization;
using ToonNet.Core.Serialization.Attributes;
[ToonSerializable]
public partial class PlayerState
{
public int PlayerId { get; set; }
public Vector3 Position { get; set; }
public float Health { get; set; }
public int Score { get; set; }
}
public class NetworkManager
{
public void BroadcastState(PlayerState state)
{
// Critical path - zero allocations
string data = ToonSerializer.Serialize(state);
networkSocket.Send(data);
}
public PlayerState ReceiveState(string data)
{
// Fast deserialization
return ToonSerializer.Deserialize<PlayerState>(data);
}
}
Example 3: IoT/Embedded Systems
using ToonNet.Core.Serialization;
using ToonNet.Core.Serialization.Attributes;
[ToonSerializable]
public partial class SensorReading
{
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
public double Humidity { get; set; }
public int BatteryLevel { get; set; }
}
public class SensorDevice
{
public void SendTelemetry()
{
var reading = new SensorReading
{
Timestamp = DateTime.UtcNow,
Temperature = ReadTemperature(),
Humidity = ReadHumidity(),
BatteryLevel = GetBatteryLevel()
};
// Minimal memory footprint
var payload = ToonSerializer.Serialize(reading);
mqttClient.Publish("sensors/data", payload);
}
}
Example 4: Native AOT Application
// Project file configuration
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ToonNet.Core" />
<PackageReference Include="ToonNet.SourceGenerators" />
</ItemGroup>
</Project>
// Code
using ToonNet.Core.Serialization;
using ToonNet.Core.Serialization.Attributes;
[ToonSerializable]
public partial class Config
{
public string AppName { get; set; }
public int MaxConnections { get; set; }
}
// Works with Native AOT (no reflection!)
var config = new Config { AppName = "MyApp", MaxConnections = 100 };
var toon = ToonSerializer.Serialize(config);
๐ Supported Types
Primitive Types
string,int,long,short,byte,sbyteuint,ulong,ushortfloat,double,decimalbool,char,Guid,DateTime,DateTimeOffset
Collections
List<T>,T[]Dictionary<TKey, TValue>IEnumerable<T>,IList<T>,ICollection<T>
Complex Types
- Nested classes with
[ToonSerializable] - Nullable types (
int?,DateTime?) - Enums
Limitations
โ Not Supported:
- Abstract/interface types
- Circular references
- Types without parameterless constructor
- Generic types (not instantiated)
๐งช Testing
# Run source generator tests
cd tests/ToonNet.SourceGenerators.Tests
dotnet test
# Verify generated code
dotnet build --verbosity detailed
# Check obj/Debug/net8.0/generated/ folder
๐ Related Packages
Core:
ToonNet.Core- Core serialization (required)
Extensions:
ToonNet.Extensions.Json- JSON โ TOONToonNet.Extensions.Yaml- YAML โ TOON
Web:
ToonNet.AspNetCore- ASP.NET Core DIToonNet.AspNetCore.Mvc- MVC formatters
Development:
ToonNet.Benchmarks- Performance testsToonNet.Tests- Test suite
๐ Documentation
- Main Documentation - Complete guide
- API Guide - API reference
- Benchmarks - Performance data
๐ Requirements
- .NET 8.0 or later
- C# 12.0+ (for partial classes)
- ToonNet.Core
๐ License
MIT License - See LICENSE file for details.
๐ค Contributing
Contributions welcome! Please read CONTRIBUTING.md first.
Part of the ToonNet serialization library family.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. |
-
net8.0
- ToonNet.Core (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial 1.0.0 release with full attribute support and AOT compatibility.