SnowBank.Serialization.Json.CodeGen
7.3.2
dotnet add package SnowBank.Serialization.Json.CodeGen --version 7.3.2
NuGet\Install-Package SnowBank.Serialization.Json.CodeGen -Version 7.3.2
<PackageReference Include="SnowBank.Serialization.Json.CodeGen" Version="7.3.2" />
<PackageVersion Include="SnowBank.Serialization.Json.CodeGen" Version="7.3.2" />
<PackageReference Include="SnowBank.Serialization.Json.CodeGen" />
paket add SnowBank.Serialization.Json.CodeGen --version 7.3.2
#r "nuget: SnowBank.Serialization.Json.CodeGen, 7.3.2"
#:package SnowBank.Serialization.Json.CodeGen@7.3.2
#addin nuget:?package=SnowBank.Serialization.Json.CodeGen&version=7.3.2
#tool nuget:?package=SnowBank.Serialization.Json.CodeGen&version=7.3.2
SnowBank SDK - JSON Source Code Generator
Generates code for custom JSON converters and proxies
This package contains a source code generator that will output optimized code for application types.
- Containers: application can define a container type and a set of top-level application types (records, structs, ...) that are exchanged with other processes as JSON.
- Converters: generates custom implements of
IJsonConverter<...>
for all the types in the dependency graph. Each converter can serialize, pack and unpack instances of these types, without relying on reflection at runtime. - Proxies: generates a set of ReadOnly and Writable proxies, that expose an underlying JSON Object as a type-safe object with the same properties and types as the parent type, without having to deserialize all the properties.
How to reference
Via NuGet, simply add a PackageReference
to any project that contains your application types.
Via a git sub-module, add a ProjectReference
and flag it as a source analyzer.
<ProjectReference
Include="..\_PATH_TO_MODULE_\SnowBank.Serialization.Json.CodeGen\SnowBank.Serialization.Json.CodeGen.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
This package will only be used at build time, and should not be redistributed with the rest of tha application.
How to use
Containers
In the shared assembly that contains most of your "data" types, simply create a new static class that will act as a container, decorate it with [CrystalJsonConverter]
, and then add as many [CrystalJsonSerializable(typeof(...)]
as you have top-level data types.
The converter will walk the type dependency graph from all these types, and generate custom converters and proxies for each one. You don't need to mention any nested type or types references by properties, as they should automatically be included.
[CrystalJsonConverter]
[CrystalJsonSerializable(typeof(User))]
[CrystalJsonSerializable(typeof(Order))]
[CrystalJsonSerializable(typeof(Product))]
[CrystalJsonSerializable(typeof(Role))]
// and any other main types
public static partial class MyAppConverters
{
}
This will generate a nested type for each of these types T
, that will generate multiple types with the following suffix:
(TypeName)Converter
: implement aIJsonConverter<T>
and provides theSerialize(...)
,Pack(...)
andUnpack(...)
methods(TypeName)ReadOnly
: read-only struct that implementsIJsonReadOnlyProxy<...>
(TypeName)ReadOnly
: mutable class that implementsIJsonWritableProxy<...>
Examples
Example: how to serialize a type into a JSON literal (text, bytes, ...):
// generate the instance that you need to serialize into JSON...
User result = MethodThatReturnsUser();
// serialize into a string:
string jsonText = MyAppConverters.User.ToJson(result);
// serialize into a Slice:
Slice jsonBytes = MyAppConverters.User.ToJsonSlice(result);
// serialize into a byte[] array:
Slice jsonBytes = MyAppConverters.User.ToJsonBytes(result);
Example: how to pack a type into a JSON Object (DOM):
// generate the instance that you need to serialize into JSON...
User result = MethodThatReturnsUser();
JsonValue json = MyAppConverters.User.Pack(result);
Console.WriteLine($"- Id: {json["id"]}");
Console.WriteLine($"- FirstName: {json["firstName"]}");
Console.WriteLine($"- LastName: {json["lastName"]}");
Example: how to unpack a JSON Object back into an instance of the original type:
JsonObject obj = new();
obj["id"] = "ag007"";
obj["firstName"] = "James";
obj["lastName"] = "Bond";
// ...
Person person = MyAppConverters.User.Unpack(obj);
Console.WriteLine($"- Id: {person.Id}");
Console.WriteLine($"- FirstName: {person.FirstName}");
Console.WriteLine($"- LastName: {person.LastName}");
Example: how to work with a read-only proxy for a type:
JsonObject obj = new();
obj["id"] = "ag007";
obj["firstName"] = "James";
obj["lastName"] = "Bond";
// ...
var person = MyAppConverters.User.ToReadOnly(obj);
Console.WriteLine($"- Id: {person.Id}");
Console.WriteLine($"- FirstName: {person.FirstName}");
Console.WriteLine($"- LastName: {person.LastName}");
Observe that the read-only proxy looks identical to the original type, and note that it will only deserialize the value of a field only when it is accessed
Example: how to work with a writable proxy for a type:
JsonObject obj = new();
// ...
var person = MyAppConverters.User.ToWritable(obj);
person.Id = "ag007";
person.FirstName = "James";
person.LastName = "Bond";
Console.WriteLine($"- Id: {obj["id"]}");
Console.WriteLine($"- FirstName: {obj["firstName"]}");
Console.WriteLine($"- LastName: {obj["lastName"]}");
Observe that the writable proxy looks identical to the original type, and note that it will only touch the properties that are updated, without changing any other fields in the existing JSON object
Example: how to get a ICrystalJsonTypeResolver
that will use the generated converters for all the known types in the container.
public static T Decode<T>(JsonObject obj)
{
// this returns a resolver that will map all the application types in the container to the generated converters
var resolver = MyAppConverters.GetResolver();
// get a converter for a known type:
if (!resolver.TryGetConverterFor<Person>(out var personConverter))
{
throw new InvalidOperationException("Type not supported");
}
// use the converter to deserialize a T instance
return personConverter.Unpack(obj);
}
var obj = new JsonObject() { ["id"] = "ag007", ["firstName"] = "James", ["lastName"] = "Bond" };
var person = Decode<Person>(obj);
Console.WriteLine($"- Id: {person.Id}");
Console.WriteLine($"- FirstName: {person.FirstName}");
Console.WriteLine($"- LastName: {person.LastName}");
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
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 | |
---|---|---|---|
7.3.2 | 181 | 6/13/2025 | |
7.3.1 | 210 | 5/30/2025 | |
7.3.1-preview.2 | 144 | 5/10/2025 |