// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= Serialization in Ignite.NET

Most of the user-defined classes going through the Ignite .NET API will be trasferred over the network to other cluster nodes. These classes include:

* Cache keys and values
* Cache processors and filters (`ICacheEntryProcessor`, `ICacheEntryFilter`, `ICacheEntryEventFilter`, `ICacheEntryEventListener`)
* Compute functions (`IComputeFunc`), actions (`IComputeAction`) and jobs (`IComputeJob`)
* Services (`IService`)
* Event and Message handlers (`IEventListener`, `IEventFilter`, `IMessageListener`)

Passing objects of these classes over the network requires serialization. Ignite .NET supports the following ways of serializing user data:

* `Apache.Ignite.Core.Binary.IBinarizable` interface
* `Apache.Ignite.Core.Binary.IBinarySerializer` interface
* `System.Runtime.Serialization.ISerializable` interface
* Ignite reflective serialization (when none of the above applies)

== IBinarizable

`IBinarizable` approach provides a fine-grained control over serialization. This is a preferred way for high-performance production code.

First, implement the `IBinarizable` interface in your class:

[tabs]
--
tab:C#[]
[source,csharp]
----
public class Address : IBinarizable
{
    public string Street { get; set; }

    public int Zip { get; set; }

    public void WriteBinary(IBinaryWriter writer)
    {
        // Alphabetic field order is required for SQL DML to work.
        // Even if DML is not used, alphabetic order is recommended.
        writer.WriteString("street", Street);
        writer.WriteInt("zip", Zip);
    }

    public void ReadBinary(IBinaryReader reader)
    {
        // Read order does not matter, however, reading in the same order
        // as writing improves performance.
        Street = reader.ReadString("street");
        Zip = reader.ReadInt("zip");
    }
}
----
--

`IBinarizable` can also be implemented in raw mode, without field names. This provides the fastest and the most compact
serialization, but disables SQL queries:

[tabs]
--
tab:C#[]
[source,csharp]
----
public class Address : IBinarizable
{
    public string Street { get; set; }

    public int Zip { get; set; }

    public void WriteBinary(IBinaryWriter writer)
    {
        var rawWriter = writer.GetRawWriter();

        rawWriter.WriteString(Street);
        rawWriter.WriteInt(Zip);
    }

    public void ReadBinary(IBinaryReader reader)
    {
        // Read order must be the same as write order
        var rawReader = reader.GetRawReader();

        Street = rawReader.ReadString();
        Zip = rawReader.ReadInt();
    }
}
----
--

[NOTE]
====
[discrete]
=== Automatic GetHashCode and Equals Implementation
If an object can be serialized into a binary form, then Ignite will calculate its hash code during serialization and
write it to the resulting binary array. Also, Ignite provides a custom implementation of the equals method for the
binary object's comparison needs. This means that you do not need to override the `GetHashCode` and `Equals` methods of
your custom keys and values in order for them to be used in Ignite.
====

== IBinarySerializer

`IBinarySerializer` is similar to `IBinarizable`, but separates serialization logic from the class implementation.
This may be useful when the class code can not be modified, and serialization logic is shared between multiple classes,
etc. The following code has exactly the same serialization as in the `Address` example above:

[tabs]
--
tab:C#[]
[source,csharp]
----
public class Address : IBinarizable
{
    public string Street { get; set; }

    public int Zip { get; set; }
}

public class AddressSerializer : IBinarySerializer
{
    public void WriteBinary(object obj, IBinaryWriter writer)
    {
        var addr = (Address) obj;

        writer.WriteString("street", addr.Street);
        writer.WriteInt("zip", addr.Zip);
    }

    public void ReadBinary(object obj, IBinaryReader reader)
    {
        var addr = (Address) obj;

        addr.Street = reader.ReadString("street");
        addr.Zip = reader.ReadInt("zip");
    }
}
----
--

The `Serializer` should be specified in the configuration like this:

[tabs]
--
tab:C#[]
[source,csharp]
----
var cfg = new IgniteConfiguration
{
    BinaryConfiguration = new BinaryConfiguration
    {
        TypeConfigurations = new[]
        {
            new BinaryTypeConfiguration(typeof (Address))
            {
                Serializer = new AddressSerializer()
            }
        }
    }
};

using (var ignite = Ignition.Start(cfg))
{
  ...
}
----
--

== ISerializable

Types that implement the `System.Runtime.Serialization.ISerializable` interface will be serialized accordingly
(by calling `GetObjectData` and serialization constructor). All system features are supported: `IObjectReference`,
`IDeserializationCallback`, `OnSerializingAttribute`, `OnSerializedAttribute`, `OnDeserializingAttribute`, `OnDeserializedAttribute`.

The `GetObjectData` result is written into the Ignite binary format. The following three classes provide identical serialized representation:

[tabs]
--
tab:C#[]
[source,csharp]
----
class Reflective
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Binarizable : IBinarizable
{
    public int Id { get; set; }
    public string Name { get; set; }

    public void WriteBinary(IBinaryWriter writer)
    {
        writer.WriteInt("Id", Id);
        writer.WriteString("Name", Name);
    }

    public void ReadBinary(IBinaryReader reader)
    {
        Id = reader.ReadInt("Id");
        Name = reader.ReadString("Name");
    }
}

class Serializable : ISerializable
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Serializable() {}

    protected Serializable(SerializationInfo info, StreamingContext context)
    {
        Id = info.GetInt32("Id");
        Name = info.GetString("Name");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Id", Id);
        info.AddValue("Name", Name);
    }
}
----
--

== Ignite Reflective Serialization

Ignite reflective serialization is essentially the `IBinarizable` approach where the interface is implemented automatically
by reflecting over all fields and emitting write/read calls.

There are no requirements for this mechanism, any class or struct can be serialized including all system types, delegates,
expression trees, or anonymous types.

Use the `[NonSerialized]` attribute to filter out specific fields during serialization.

The raw mode can be enabled by specifying `BinaryReflectiveSerializer` explicitly:

[tabs]
--
tab:C#[]
[source,csharp]
----
var binaryConfiguration = new BinaryConfiguration
{
    TypeConfigurations = new[]
    {
        new BinaryTypeConfiguration(typeof(MyClass))
        {
            Serializer = new BinaryReflectiveSerializer {RawMode = true}
        }
    }
};
----
tab:app.config[]
[source,xml]
----
<igniteConfiguration>
    <binaryConfiguration>
        <typeConfigurations>
            <binaryTypeConfiguration typeName='Apache.Ignite.ExamplesDll.Binary.Address'>
                <serializer type='Apache.Ignite.Core.Binary.BinaryReflectiveSerializer, Apache.Ignite.Core' rawMode='true' />
            </binaryTypeConfiguration>
        </typeConfigurations>
    </binaryConfiguration>
</igniteConfiguration>
----
--

Otherwise, `BinaryConfiguration` is not required.

Performance is identical to manual the `IBinarizable` approach. Reflection is only used on startup to iterate over the
fields and emit efficient IL code.

Types marked with `[Serializable]` attribute but without `ISerializable` interface are written with Ignite reflective serializer.

== Using Entity Framework POCOs

The Entity Framework POCOs can be used directly with Ignite.

However, https://msdn.microsoft.com/en-us/data/jj592886.aspx[POCO proxies, window=_blank] cannot be directly serialized
or deserialized by Ignite, because the proxy type is a dynamic type.

Make sure to disable proxy creation when using EF objects with Ignite:

[tabs]
--
tab:Entity Framework 6[]
[source,csharp]
----
ctx.Configuration.ProxyCreationEnabled = false;
----
tab:Entity Framework 5[]
[source,csharp]
----
ctx.ContextOptions.ProxyCreationEnabled = false;
----
--

== More Info

See https://ptupitsyn.github.io/Ignite-Serialization-Performance/[Ignite Serialization Performance, window=_blank] blog
post for more details on serialization performance of various modes introduced on this page.
