Nino Documentation

website·Indexed 30 days ago

https://nino.xgamedev.net

Documentation for Nino, including installation guides, basic and advanced usage, type system specifications, versioning, and performance microbenchmarks comparing it to MessagePack and MemoryPack.

Tokens
4.9K
Snippets
21
Records
30
Agent score
52%

What's inside Nino

  1. Handle type or namespace renaming for backward compatibility

    Nino allows you to rename a type or its namespace while maintaining the ability to deserialize data created with the old name. This is achieved by adding the [NinoFormerName] attribute to the renamed type. For generic types, only the old type name and namespace are required; generic parameters should be omitted. The exact old name can be found in the generated NinoTypeConst.g.cs file.
    [NinoType]
    [NinoFormerName("global::Nino.UnitTests.Generic")]
    public class GenericRenamed<T> 
    {
        // ...
    }
    
    [NinoType]
    [NinoFormerName("global::ListElementClass2")]
    public class ListElementClass2Renamed 
    {
        // ...
    }
  2. Control constructor selection in C# Records

    Nino handles C# records with different constructor strategies:

    1. Primary Constructors: By default, Nino prefers the primary constructor of a record.
    2. Overriding Primary Constructors: If a record has a primary constructor but you want Nino to use a different one, mark the desired constructor with [NinoConstructor].
    3. Caveat: If you mark a parameterless constructor with [NinoConstructor] on a record that has a primary constructor, Nino will use the parameterless one, effectively discarding the values that would have been passed to the primary constructor during deserialization.
    // Case 1: Primary constructor is used automatically
    [NinoType]
    public record SimpleRecord4(int Id, string Name, DateTime CreateTime)
    {
        [NinoIgnore] public bool Flag;
        public int ShouldNotIgnore;
    
        public SimpleRecord4() : this(0, "", DateTime.MinValue) { }
    }
    
    // Case 2: Primary constructor is ignored because [NinoConstructor] is on the parameterless one
    [NinoType]
    public record SimpleRecord5(int Id, string Name, DateTime CreateTime)
    {
        [NinoConstructor]
        public SimpleRecord5() : this(0, "", DateTime.MinValue) { }
    }
  3. Install Nino in a .NET project

    Nino supports projects with .NET 5.0 or higher, or .NET Standard 2.0 or higher. It requires two specific NuGet packages: Nino.Generator and Nino.Serialization. Installing the main Nino package automatically includes both. Note that .NET Framework projects and IDEs that do not support Source Generators are not supported.
    dotnet add package Nino
  4. Serialize generic and collection types in Nino

    Nino supports generic types and a wide range of collection types, provided the type arguments are also serializable. Supported collections include List<T>, Dictionary<TKey, TValue>, T[], ICollection<T>, IDictionary<TKey, TValue>, Span<T>, HashSet<T>, and ArraySegment<T>.

    Critical Requirement for Dictionaries: When creating a subtype of a dictionary, you must define a public indexer, otherwise no serialization/deserialization code will be generated.

    [NinoType]
    public class Generic<T>
    {
        public T Val;
    }
    
    // Dictionary subtype example with required indexer
    public class MultiMap<T, K> : SortedDictionary<T, List<K>>
    {
        public new List<K> this[T key]
        {
            get { /* implementation */ }
            set { /* implementation */ }
        }
    }
  5. Serialize data using Nino

    Nino provides a Serializer class to convert NinoSerializableType objects into byte arrays. You can either use the static Serializer.Serialize method or the Serialize() extension method on the object itself.
    ObjClass obj = new ObjClass();
    // Standard static method
    byte[] byteArr = Serializer.Serialize(obj);
    
    // Using extension method
    byteArr = obj.Serialize();
  6. Understand Nino current technical limitations

    When using Nino, be aware of the following constraints:

    • Source Generator Requirement: Nino must be used with a Source Generator.
    • Version Tolerance Compatibility: Projects defined with WEAK_VERSION_TOLERANCE cannot deserialize data from projects without it, and vice versa.
    • Unsupported Types: Attempting to serialize unsupported types (e.g., Queue) will result in a compilation error.
    • ValueTuple Platform Incompatibility: ValueTuple is not compatible between .NET Core and Unity/Mono. This is due to differing struct layout implementations (LayoutKind.Auto in .NET Core vs sequential layout in Mono), which leads to different serialization results.
  7. Deserialize data using Nino

    The Deserializer.Deserialize method converts a ReadOnlySpan<byte> back into a NinoSerializableType. The method accepts byte[], ArraySegment<byte>, Span<byte>, or Memory<byte>.Span as the data source.
    // Assuming byteArr is byte[]
    Deserializer.Deserialize(byteArr, out ObjClass obj);
  8. Migrate from Nino v2 to v3

    To migrate from Nino v2 to the latest version, update the library and update the namespace of the generated code from AssemblyName_Nino to AssemblyName.NinoGen.
  9. Serialize non-public fields and properties in Nino

    Nino supports serializing non-public fields and properties (implemented in v3.0.6), but requirements vary by .NET version:

    • .NET 8.0 and above: No restrictions.
    • Below .NET 8.0:
      • The type containing private members must have the partial modifier (e.g., partial class MyClass).
      • Private members cannot be defined within serializable nested types.
  10. Install Nino in a Unity project

    Nino supports Unity 2022.3 or higher across all player platforms. Installation is performed via the Unity Package Manager (UPM).

    Crucially, Microsoft.CodeAnalysis must be installed to support Source Generators. While Unity 2022.3+ usually includes it, you can install it manually by running the dotnet command from the Unity root directory (the folder containing the Assets folder).

    dotnet add package Microsoft.CodeAnalysis.CSharp --version 4.10.0
  11. Use Nino with Unity Hot Update (HybridCLR or ILRuntime)

    Nino supports HybridCLR and ILRuntime. To write hot update code in an external C# project (outside of a Unity asmdef), create a .NET Core project, install the Nino library via NuGet, and then use the resulting compiled DLL within HybridCLR or ILRuntime.
  12. Handle polymorphic types, interfaces, and abstract classes

    Nino supports polymorphism, interfaces, and abstract classes. For these to work, every involved type (the interface/base class AND all implementation/derived classes) must be decorated with the [NinoType] attribute. When a derived class is serialized as its base type, Nino preserves the actual derived type and restores it correctly during deserialization.
    [NinoType]
    public abstract class Base
    {
        public int A { get; set; }
    }
    
    [NinoType]
    public class Derived : Base
    {
        public int B { get; set; }
    }
    
    // Usage
    var list = new List<Base> { new Base { A = 1 }, new Derived { A = 2, B = 3 } };
    var bytes = Serializer.Serialize(list);
    Deserializer.Deserialize(bytes, out List<Base> result);
    // result[1] will be correctly restored as a Derived object