Serialization
Serialization in Ignite.NET
Ignite .NET API'sinden geçen kullanıcı tanımlı sınıfların çoğu, ağ üzerinden diğer cluster nodelarına aktarılacaktır. Bu sınıflar şunları içerir:
- Cache keyler ve valueları
- Cache processor’leri ve filtreler (
ICacheEntryProcessor
,ICacheEntryFilter
,ICacheEntryEventFilter
,ICacheEntryEventListener
) - Compute functionları(
IComputeFunc
), actionları(IComputeAction
) ve jobları(IComputeJob
) - Hizmetler (IService)
- Evebt ve Mesaj işleyicileri (
IEventListener
,IEventFilter
,IMessageListener
)
Bu sınıfların nesnelerini ağ üzerinden geçirmek serialization gerektirir. Ignite .NET, kullanıcı verilerini serialize etmenin aşağıdaki yollarını destekler:
Apache.Ignite.Core.Binary.IBinarizable
interfaceApache.Ignite.Core.Binary.IBinarySerializer
interfaceSystem.Runtime.Serialization.ISerializable
interface- Ignite reflective serialization (yukarıdakilerin hiçbiri geçerli olmadığında)
IBinarizable
IBinarizable
yaklaşımı, serialization üzerinde ayrıntılı bir kontrol sağlar. Bu, yüksek performanslı production kodu için tercih edilen bir yoldur.
İlk olarak, sınıfınızda IBinarizable
interface’ini uygulayın:
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
, alan adları olmadan raw modda da uygulanabilir. Bu, en hızlı ve en kompakt serialization’u sağlar, ancak SQL sorgularını devre dışı bırakır:
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();
}
}
Automatic GetHashCode and Equals Implementation
Bir nesne binary bir biçimde serialize edilebiliyorsa, Ignite serialization sırasında hash kodunu hesaplayacak ve onu elde edilen binary array’e yazacaktır. Ayrıca Ignite, binary nesnenin karşılaştırma gereksinimleri için equals methodunun özel bir implementasyonunu sağlar. Bu, Ignite'ta kullanılmaları için custom key’lerin ve valueların GetHashCode ve Equals methodlarını geçersiz kılmanız gerekmediği anlamına gelir.
IBinarySerializer
IBinarySerializer
, IBinarizable
'a benzer, ancak serialization mantığını class implementasyonundan ayırır. Bu, sınıf kodu değiştirilemediğinde ve serialization mantığı birden çok sınıf arasında paylaşıldığında yararlı olabilir. Aşağıdaki kod, yukarıdaki Address
örneğindekiyle tam olarak aynı serialization’a sahiptir:
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");
}
}
Oluşturulan serializer aşağıdaki şekilde yapılandırmada belirtilmelidir:
var cfg = new IgniteConfiguration
{
BinaryConfiguration = new BinaryConfiguration
{
TypeConfigurations = new[]
{
new BinaryTypeConfiguration(typeof (Address))
{
Serializer = new AddressSerializer()
}
}
}
};
using (var ignite = Ignition.Start(cfg))
{
...
}
ISerializable
System.Runtime.Serialization.ISerializable
interface’ini implemente eden türler buna göre serialize edilir (GetObjectData
ve serialization constructor’u çağrılarak). Tüm sistem özellikleri desteklenir: IObjectReference
, IDeserializationCallback
, OnSerializingAttribute
, OnSerializedAttribute
, OnDeserializingAttribute
, OnDeserializedAttribute
.
GetObjectData
sonucu, Ignite’a binary biçiminde yazılır. Aşağıdaki üç sınıf, aynı serialize edilmiş temsili sağlar:
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, esas olarak interface’in tüm alanları yansıtarak ve yazma/okuma çağrıları yayarak otomatik olarak implemte edildiği IBinarizable
yaklaşımıdır.
Bu mekanizma için herhangi bir gereksinim yoktur, tüm sistem türleri, delegateler, expression tree’ler veya anonymous type’lar dahil olmak üzere herhangi bir sınıf veya yapı serialize edilebilir.
Serialization sırasında belirli alanları filtrelemek için [NonSerialized]
özelliğini kullanın.
Raw mod, BinaryReflectiveSerializer
doğrudan belirtilerek etkinleştirilebilir:
var binaryConfiguration = new BinaryConfiguration
{
TypeConfigurations = new[]
{
new BinaryTypeConfiguration(typeof(MyClass))
{
Serializer = new BinaryReflectiveSerializer {RawMode = true}
}
}
};
Aksi takdirde, BinaryConfiguration
gerekli değildir.
Performans, manuel IBinarizable
yaklaşımıyla aynıdır. Reflection, alanlar üzerinde yineleme yapmak ve verimli IL kodu yaymak için yalnızca başlangıçta kullanılır.
[Serializable]
attribute’u ile işaretlenen ancak ISerializable
interface’i olmayan tipler, Ignite reflective serializer ile yazılır.