Repository: ignite
Updated Branches:
  refs/heads/master fbba10219 -> ead2b1f5a


IGNITE-3097 .NET: Improve reflective serialization performance

This closes #698


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ead2b1f5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ead2b1f5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ead2b1f5

Branch: refs/heads/master
Commit: ead2b1f5aa0637e82b55a8071dd9af911f25f2a3
Parents: fbba102
Author: Pavel Tupitsyn <ptupit...@apache.org>
Authored: Fri Jun 17 19:29:33 2016 +0300
Committer: Pavel Tupitsyn <ptupit...@apache.org>
Committed: Fri Jun 17 19:29:33 2016 +0300

----------------------------------------------------------------------
 .../IgniteOutputCacheProvider.cs                |   6 +-
 .../Apache.Ignite.Core.csproj                   |   6 +-
 .../Binary/BinaryReflectiveSerializer.cs        | 193 ++-----------------
 .../Binary/UserSerializerProxy.cs               |  68 +++++++
 .../Impl/Binary/BinarizableSerializer.cs        |  22 ++-
 .../Impl/Binary/BinaryFullTypeDescriptor.cs     |   8 +-
 .../Impl/Binary/BinaryReader.cs                 |  38 +---
 .../BinaryReflectiveSerializerInternal.cs       | 169 ++++++++++++++++
 .../Binary/BinarySurrogateTypeDescriptor.cs     |   4 +-
 .../Impl/Binary/BinarySystemTypeSerializer.cs   |  20 +-
 .../Impl/Binary/BinaryWriter.cs                 |   2 +-
 .../Impl/Binary/DateTimeSerializer.cs           |  48 +++++
 .../Impl/Binary/IBinarySerializerInternal.cs    |  42 ++++
 .../Impl/Binary/IBinarySystemTypeSerializer.cs  |  34 ----
 .../Impl/Binary/IBinaryTypeDescriptor.cs        |   2 +-
 .../Impl/Binary/Marshaller.cs                   |  77 ++++----
 .../Impl/Binary/SerializableSerializer.cs       |  48 +++++
 17 files changed, 480 insertions(+), 307 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs 
b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
index d6006e5..fb7a15d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteOutputCacheProvider.cs
@@ -190,10 +190,10 @@ namespace Apache.Ignite.AspNet
                 return Cache;
 
             // Round up to seconds ([OutputCache] duration is in seconds).
-            var expirySeconds = (long) (utcExpiry - 
DateTime.UtcNow).TotalSeconds;
+            var expirySeconds = (long) Math.Round((utcExpiry - 
DateTime.UtcNow).TotalSeconds);
 
-            if (expirySeconds < 1)
-                expirySeconds = 1;
+            if (expirySeconds < 0)
+                expirySeconds = 0;
 
             ICache<string, object> expiryCache;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj 
b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 4cfd4e5..34c5ddb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -84,7 +84,10 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Binary\BinaryReflectiveSerializer.cs" />
+    <Compile Include="Impl\Binary\BinaryReflectiveSerializerInternal.cs" />
+    <Compile Include="Impl\Binary\IBinarySerializerInternal.cs" />
     <Compile Include="Binary\Package-Info.cs" />
+    <Compile Include="Binary\UserSerializerProxy.cs" />
     <Compile Include="Cache\Affinity\AffinityFunctionBase.cs" />
     <Compile Include="Cache\Affinity\AffinityKey.cs" />
     <Compile Include="Cache\Affinity\AffinityKeyMappedAttribute.cs" />
@@ -156,6 +159,8 @@
     <Compile Include="Common\IgniteFutureCancelledException.cs" />
     <Compile Include="Common\IgniteGuid.cs" />
     <Compile Include="Common\Package-Info.cs" />
+    <Compile Include="Impl\Binary\DateTimeSerializer.cs" />
+    <Compile Include="Impl\Binary\SerializableSerializer.cs" />
     <Compile Include="Impl\Binary\BinaryWriterExtensions.cs" />
     <Compile Include="Impl\Common\Platform.cs" />
     <Compile Include="Impl\Cache\Event\JavaCacheEntryEventFilter.cs" />
@@ -348,7 +353,6 @@
     <Compile Include="Impl\Binary\IO\BinaryStreamBase.cs" />
     <Compile Include="Impl\Binary\IO\BinaryHeapStream.cs" />
     <Compile Include="Impl\Binary\IO\BinaryStreamAdapter.cs" />
-    <Compile Include="Impl\Binary\IBinarySystemTypeSerializer.cs" />
     <Compile Include="Impl\Binary\IBinaryTypeDescriptor.cs" />
     <Compile Include="Impl\Binary\IBinaryWriteAware.cs" />
     <Compile Include="Impl\Binary\Metadata\IBinaryTypeHandler.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs
index 02703be..18e8c2d 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryReflectiveSerializer.cs
@@ -18,8 +18,6 @@
 namespace Apache.Ignite.Core.Binary
 {
     using System;
-    using System.Collections.Generic;
-    using System.Reflection;
     using Apache.Ignite.Core.Impl.Binary;
 
     /// <summary>
@@ -41,16 +39,24 @@ namespace Apache.Ignite.Core.Binary
     /// </summary>
     public sealed class BinaryReflectiveSerializer : IBinarySerializer
     {
-        /** Cached binding flags. */
-        private const BindingFlags Flags = BindingFlags.Instance | 
BindingFlags.Public | 
-            BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
-
-        /** Cached type descriptors. */
-        private readonly IDictionary<Type, Descriptor> _types = new 
Dictionary<Type, Descriptor>();
-
         /** Raw mode flag. */
         private bool _rawMode;
 
+        /** In use flag. */
+        private bool _isInUse;
+
+        /** <inheritdoc /> */
+        public void WriteBinary(object obj, IBinaryWriter writer)
+        {
+            throw new NotSupportedException(GetType() + ".WriteBinary should 
not be called directly.");
+        }
+
+        /** <inheritdoc /> */
+        public void ReadBinary(object obj, IBinaryReader reader)
+        {
+            throw new NotSupportedException(GetType() + ".ReadBinary should 
not be called directly.");
+        }
+
         /// <summary>
         /// Gets or value indicating whether raw mode serialization should be 
used.
         /// <para />
@@ -62,8 +68,8 @@ namespace Apache.Ignite.Core.Binary
             get { return _rawMode; }
             set
             {
-                if (_types.Count > 0)
-                    throw new InvalidOperationException(typeof 
(BinarizableSerializer).Name +
+                if (_isInUse)
+                    throw new 
InvalidOperationException(typeof(BinaryReflectiveSerializer).Name +
                         ".RawMode cannot be changed after first 
serialization.");
 
                 _rawMode = value;
@@ -71,171 +77,14 @@ namespace Apache.Ignite.Core.Binary
         }
 
         /// <summary>
-        /// Write portalbe object.
-        /// </summary>
-        /// <param name="obj">Object.</param>
-        /// <param name="writer">Writer.</param>
-        /// <exception cref="BinaryObjectException">Type is not registered in 
serializer:  + type.Name</exception>
-        public void WriteBinary(object obj, IBinaryWriter writer)
-        {
-            var binarizable = obj as IBinarizable;
-
-            if (binarizable != null)
-                binarizable.WriteBinary(writer);
-            else
-                GetDescriptor(obj).Write(obj, writer);
-        }
-
-        /// <summary>
-        /// Read binary object.
+        /// Registers the specified type.
         /// </summary>
-        /// <param name="obj">Instantiated empty object.</param>
-        /// <param name="reader">Reader.</param>
-        /// <exception cref="BinaryObjectException">Type is not registered in 
serializer:  + type.Name</exception>
-        public void ReadBinary(object obj, IBinaryReader reader)
-        {
-            var binarizable = obj as IBinarizable;
-            
-            if (binarizable != null)
-                binarizable.ReadBinary(reader);
-            else
-                GetDescriptor(obj).Read(obj, reader);
-        }
-
-        /// <summary>Register type.</summary>
-        /// <param name="type">Type.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="converter">Name converter.</param>
-        /// <param name="idMapper">ID mapper.</param>
-        internal void Register(Type type, int typeId, IBinaryNameMapper 
converter,
+        internal IBinarySerializerInternal Register(Type type, int typeId, 
IBinaryNameMapper converter,
             IBinaryIdMapper idMapper)
         {
-            if (type.GetInterface(typeof(IBinarizable).Name) != null)
-                return;
-
-            List<FieldInfo> fields = new List<FieldInfo>();
-
-            Type curType = type;
-
-            while (curType != null)
-            {
-                foreach (FieldInfo field in curType.GetFields(Flags))
-                {
-                    if (!field.IsNotSerialized)
-                        fields.Add(field);
-                }
-
-                curType = curType.BaseType;
-            }
-
-            IDictionary<int, string> idMap = new Dictionary<int, string>();
-
-            foreach (FieldInfo field in fields)
-            {
-                string fieldName = BinaryUtils.CleanFieldName(field.Name);
-
-                int fieldId = BinaryUtils.FieldId(typeId, fieldName, 
converter, idMapper);
-
-                if (idMap.ContainsKey(fieldId))
-                {
-                    throw new BinaryObjectException("Conflicting field IDs 
[type=" +
-                        type.Name + ", field1=" + idMap[fieldId] + ", field2=" 
+ fieldName +
-                        ", fieldId=" + fieldId + ']');
-                }
-                
-                idMap[fieldId] = fieldName;
-            }
-
-            fields.Sort(Compare);
-
-            Descriptor desc = new Descriptor(fields, _rawMode);
-
-            _types[type] = desc;
-        }
-
-        /// <summary>
-        /// Gets the descriptor for an object.
-        /// </summary>
-        private Descriptor GetDescriptor(object obj)
-        {
-            var type = obj.GetType();
-
-            Descriptor desc;
-
-            if (!_types.TryGetValue(type, out desc))
-                throw new BinaryObjectException("Type is not registered in 
serializer: " + type.Name);
-
-            return desc;
-        }
-        
-        /// <summary>
-        /// Compare two FieldInfo instances. 
-        /// </summary>
-        private static int Compare(FieldInfo info1, FieldInfo info2) {
-            string name1 = BinaryUtils.CleanFieldName(info1.Name);
-            string name2 = BinaryUtils.CleanFieldName(info2.Name);
-
-            return string.Compare(name1, name2, 
StringComparison.OrdinalIgnoreCase);
-        }
-
-        /// <summary>
-        /// Type descriptor. 
-        /// </summary>
-        private class Descriptor
-        {
-            /** Write actions to be performed. */
-            private readonly List<BinaryReflectiveWriteAction> _wActions;
+            _isInUse = true;
 
-            /** Read actions to be performed. */
-            private readonly List<BinaryReflectiveReadAction> _rActions;
-
-            /// <summary>
-            /// Constructor.
-            /// </summary>
-            /// <param name="fields">Fields.</param>
-            /// <param name="raw">Raw mode.</param>
-            public Descriptor(List<FieldInfo> fields, bool raw)
-            {
-                _wActions = new 
List<BinaryReflectiveWriteAction>(fields.Count);
-                _rActions = new List<BinaryReflectiveReadAction>(fields.Count);
-
-                foreach (FieldInfo field in fields)
-                {
-                    BinaryReflectiveWriteAction writeAction;
-                    BinaryReflectiveReadAction readAction;
-
-                    BinaryReflectiveActions.GetTypeActions(field, out 
writeAction, out readAction, raw);
-
-                    _wActions.Add(writeAction);
-                    _rActions.Add(readAction);
-                }
-            }
-
-            /// <summary>
-            /// Write object.
-            /// </summary>
-            /// <param name="obj">Object.</param>
-            /// <param name="writer">Writer.</param>
-            public void Write(object obj, IBinaryWriter writer)
-            {
-                int cnt = _wActions.Count;
-
-                for (int i = 0; i < cnt; i++)
-                    _wActions[i](obj, writer);                   
-            }
-
-            /// <summary>
-            /// Read object.
-            /// </summary>
-            /// <param name="obj">Object.</param>
-            /// <param name="reader">Reader.</param>
-            public void Read(object obj, IBinaryReader reader)
-            {
-                int cnt = _rActions.Count;
-
-                for (int i = 0; i < cnt; i++ )
-                    _rActions[i](obj, reader);
-            }
+            return new 
BinaryReflectiveSerializerInternal(_rawMode).Register(type, typeId, converter, 
idMapper);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Binary/UserSerializerProxy.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/UserSerializerProxy.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/UserSerializerProxy.cs
new file mode 100644
index 0000000..2cfc95e
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/UserSerializerProxy.cs
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Binary
+{
+    using System;
+    using System.Diagnostics;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Impl.Binary;
+
+    /// <summary>
+    /// User-defined serializer wrapper.
+    /// </summary>
+    internal class UserSerializerProxy : IBinarySerializerInternal
+    {
+        /** */
+        private readonly IBinarySerializer _serializer;
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="UserSerializerProxy"/> class.
+        /// </summary>
+        /// <param name="serializer">The serializer.</param>
+        public UserSerializerProxy(IBinarySerializer serializer)
+        {
+            Debug.Assert(serializer != null);
+
+            _serializer = serializer;
+        }
+
+        /** <inheritdoc /> */
+        public void WriteBinary<T>(T obj, BinaryWriter writer)
+        {
+            _serializer.WriteBinary(obj, writer);
+        }
+
+        /** <inheritdoc /> */
+        public T ReadBinary<T>(BinaryReader reader, Type type, int pos)
+        {
+            var obj = FormatterServices.GetUninitializedObject(type);
+
+            reader.AddHandle(pos, obj);
+
+            _serializer.ReadBinary(obj, reader);
+
+            return (T) obj;
+        }
+
+        /** <inheritdoc /> */
+        public bool SupportsHandles
+        {
+            get { return true; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs
index aa6144b..dcb261f 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarizableSerializer.cs
@@ -17,13 +17,15 @@
 
 namespace Apache.Ignite.Core.Impl.Binary
 {
+    using System;
+    using System.Runtime.Serialization;
     using Apache.Ignite.Core.Binary;
 
     /// <summary>
     /// Binary serializer which only supports <see cref="IBinarizable"/> types 
with a default ctor.
     /// Does not use reflection.
     /// </summary>
-    internal class BinarizableSerializer : IBinarySerializer
+    internal class BinarizableSerializer : IBinarySerializerInternal
     {
         /// <summary>
         /// Default instance.
@@ -31,15 +33,27 @@ namespace Apache.Ignite.Core.Impl.Binary
         public static readonly BinarizableSerializer Instance = new 
BinarizableSerializer();
 
         /** <inheritdoc /> */
-        public void WriteBinary(object obj, IBinaryWriter writer)
+        public void WriteBinary<T>(T obj, BinaryWriter writer)
         {
-            ((IBinarizable)obj).WriteBinary(writer);
+            ((IBinarizable) obj).WriteBinary(writer);
         }
 
         /** <inheritdoc /> */
-        public void ReadBinary(object obj, IBinaryReader reader)
+        public T ReadBinary<T>(BinaryReader reader, Type type, int pos)
         {
+            var obj = (T) FormatterServices.GetUninitializedObject(type);
+
+            reader.AddHandle(pos, obj);
+
             ((IBinarizable)obj).ReadBinary(reader);
+
+            return obj;
+        }
+
+        /** <inheritdoc /> */
+        public bool SupportsHandles
+        {
+            get { return true; }
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
index ac86770..6dc5d4d 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
@@ -46,7 +46,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         private readonly IBinaryIdMapper _idMapper;
 
         /** Serializer. */
-        private readonly IBinarySerializer _serializer;
+        private readonly IBinarySerializerInternal _serializer;
 
         /** Whether to cache deserialized value in IBinaryObject */
         private readonly bool _keepDeserialized;
@@ -85,8 +85,8 @@ namespace Apache.Ignite.Core.Impl.Binary
             string typeName, 
             bool userType, 
             IBinaryNameMapper nameMapper, 
-            IBinaryIdMapper idMapper, 
-            IBinarySerializer serializer, 
+            IBinaryIdMapper idMapper,
+            IBinarySerializerInternal serializer, 
             bool keepDeserialized, 
             string affKeyFieldName,
             bool isEnum)
@@ -162,7 +162,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Serializer.
         /// </summary>
-        public IBinarySerializer Serializer
+        public IBinarySerializerInternal Serializer
         {
             get { return _serializer; }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
index 1403410..3ca7ec6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
@@ -22,7 +22,6 @@ namespace Apache.Ignite.Core.Impl.Binary
     using System.Collections.Generic;
     using System.Diagnostics.CodeAnalysis;
     using System.IO;
-    using System.Runtime.Serialization;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
     using Apache.Ignite.Core.Impl.Binary.Structure;
@@ -725,29 +724,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                     // Read object.
                     Stream.Seek(pos + BinaryObjectHeader.Size, 
SeekOrigin.Begin);
 
-                    object obj;
-
-                    var sysSerializer = desc.Serializer as 
IBinarySystemTypeSerializer;
-
-                    if (sysSerializer != null)
-                        obj = sysSerializer.ReadInstance(this);
-                    else
-                    {
-                        try
-                        {
-                            obj = 
FormatterServices.GetUninitializedObject(desc.Type);
-
-                            // Save handle.
-                            AddHandle(pos, obj);
-                        }
-                        catch (Exception e)
-                        {
-                            throw new BinaryObjectException("Failed to create 
type instance: " +
-                                                        
desc.Type.AssemblyQualifiedName, e);
-                        }
-
-                        desc.Serializer.ReadBinary(obj, this);
-                    }
+                    var obj = desc.Serializer.ReadBinary<T>(this, desc.Type, 
pos);
 
                     _curStruct.UpdateReaderStructure();
 
@@ -759,18 +736,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                     _curSchema = oldSchema;
                     _curSchemaMap = oldSchemaMap;
 
-                    // Process wrappers. We could introduce a common 
interface, but for only 2 if-else is faster.
-                    var wrappedSerializable = obj as SerializableObjectHolder;
-
-                    if (wrappedSerializable != null) 
-                        return (T) wrappedSerializable.Item;
-
-                    var wrappedDateTime = obj as DateTimeHolder;
-
-                    if (wrappedDateTime != null)
-                        return TypeCaster<T>.Cast(wrappedDateTime.Item);
-                    
-                    return (T) obj;
+                    return obj;
                 }
             }
             finally

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs
new file mode 100644
index 0000000..c9fd3cc
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveSerializerInternal.cs
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Reflection;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Binary;
+
+    /// <summary>
+    /// Internal reflective serializer.
+    /// </summary>
+    internal sealed class BinaryReflectiveSerializerInternal : 
IBinarySerializerInternal
+    {
+        /** Cached binding flags. */
+        private const BindingFlags Flags = BindingFlags.Instance | 
BindingFlags.Public |
+                                           BindingFlags.NonPublic | 
BindingFlags.DeclaredOnly;
+
+        /** Raw mode flag. */
+        private readonly bool _rawMode;
+
+        /** Write actions to be performed. */
+        private readonly BinaryReflectiveWriteAction[] _wActions;
+
+        /** Read actions to be performed. */
+        private readonly BinaryReflectiveReadAction[] _rActions;
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="BinaryReflectiveSerializer"/> class.
+        /// </summary>
+        public BinaryReflectiveSerializerInternal(bool raw)
+        {
+            _rawMode = raw;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="BinaryReflectiveSerializer"/> class.
+        /// </summary>
+        private 
BinaryReflectiveSerializerInternal(BinaryReflectiveWriteAction[] wActions, 
BinaryReflectiveReadAction[] rActions, bool raw)
+        {
+            Debug.Assert(wActions != null);
+            Debug.Assert(rActions != null);
+
+            _wActions = wActions;
+            _rActions = rActions;
+            _rawMode = raw;
+        }
+
+        /** <inheritdoc /> */
+        void IBinarySerializerInternal.WriteBinary<T>(T obj, BinaryWriter 
writer)
+        {
+            Debug.Assert(_wActions != null);
+
+            foreach (var action in _wActions)
+                action(obj, writer);
+        }
+
+        /** <inheritdoc /> */
+        T IBinarySerializerInternal.ReadBinary<T>(BinaryReader reader, Type 
type, int pos)
+        {
+            Debug.Assert(_rActions != null);
+
+            var obj = FormatterServices.GetUninitializedObject(type);
+
+            reader.AddHandle(pos, obj);
+
+            foreach (var action in _rActions)
+                action(obj, reader);
+
+            return (T) obj;
+        }
+
+        /** <inheritdoc /> */
+        bool IBinarySerializerInternal.SupportsHandles
+        {
+            get { return true; }
+        }
+
+        /// <summary>Register type.</summary>
+        /// <param name="type">Type.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="converter">Name converter.</param>
+        /// <param name="idMapper">ID mapper.</param>
+        internal BinaryReflectiveSerializerInternal Register(Type type, int 
typeId, IBinaryNameMapper converter,
+            IBinaryIdMapper idMapper)
+        {
+            Debug.Assert(_wActions == null && _rActions == null);
+
+            List<FieldInfo> fields = new List<FieldInfo>();
+
+            Type curType = type;
+
+            while (curType != null)
+            {
+                foreach (FieldInfo field in curType.GetFields(Flags))
+                {
+                    if (!field.IsNotSerialized)
+                        fields.Add(field);
+                }
+
+                curType = curType.BaseType;
+            }
+
+            IDictionary<int, string> idMap = new Dictionary<int, string>();
+
+            foreach (FieldInfo field in fields)
+            {
+                string fieldName = BinaryUtils.CleanFieldName(field.Name);
+
+                int fieldId = BinaryUtils.FieldId(typeId, fieldName, 
converter, idMapper);
+
+                if (idMap.ContainsKey(fieldId))
+                {
+                    throw new BinaryObjectException("Conflicting field IDs 
[type=" +
+                                                    type.Name + ", field1=" + 
idMap[fieldId] + ", field2=" + fieldName +
+                                                    ", fieldId=" + fieldId + 
']');
+                }
+
+                idMap[fieldId] = fieldName;
+            }
+
+            fields.Sort(Compare);
+
+            var wActions = new BinaryReflectiveWriteAction[fields.Count];
+            var rActions = new BinaryReflectiveReadAction[fields.Count];
+
+            for (int i = 0; i < fields.Count; i++)
+            {
+                BinaryReflectiveWriteAction writeAction;
+                BinaryReflectiveReadAction readAction;
+
+                BinaryReflectiveActions.GetTypeActions(fields[i], out 
writeAction, out readAction, _rawMode);
+
+                wActions[i] = writeAction;
+                rActions[i] = readAction;
+            }
+
+            return new BinaryReflectiveSerializerInternal(wActions, rActions, 
_rawMode);
+        }
+
+        /// <summary>
+        /// Compare two FieldInfo instances. 
+        /// </summary>
+        private static int Compare(FieldInfo info1, FieldInfo info2)
+        {
+            string name1 = BinaryUtils.CleanFieldName(info1.Name);
+            string name2 = BinaryUtils.CleanFieldName(info2.Name);
+
+            return string.Compare(name1, name2, 
StringComparison.OrdinalIgnoreCase);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
index 04028b5..16e3032 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
@@ -113,9 +113,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /** <inheritDoc /> */
-        public IBinarySerializer Serializer
+        public IBinarySerializerInternal Serializer
         {
-            get { return _cfg.DefaultSerializer; }
+            get { return new UserSerializerProxy(_cfg.DefaultSerializer); }
         }
 
         /** <inheritDoc /> */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
index cc145e9..b416848 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemTypeSerializer.cs
@@ -19,13 +19,13 @@ namespace Apache.Ignite.Core.Impl.Binary
 {
     using System;
     using System.Diagnostics;
-    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
     /// Binary serializer for system types.
     /// </summary>
     /// <typeparam name="T">Object type.</typeparam>
-    internal class BinarySystemTypeSerializer<T> : IBinarySystemTypeSerializer 
where T : IBinaryWriteAware
+    internal class BinarySystemTypeSerializer<T> : IBinarySerializerInternal 
where T : IBinaryWriteAware
     {
         /** Ctor delegate. */
         private readonly Func<BinaryReader, T> _ctor;
@@ -41,22 +41,22 @@ namespace Apache.Ignite.Core.Impl.Binary
             _ctor = ctor;
         }
 
-        /** <inheritdoc /> */
-        public void WriteBinary(object obj, IBinaryWriter writer)
+        /** <inheritDoc /> */
+        public void WriteBinary<T1>(T1 obj, BinaryWriter writer)
         {
-            ((T) obj).WriteBinary(writer);
+            TypeCaster<T>.Cast(obj).WriteBinary(writer);
         }
 
-        /** <inheritdoc /> */
-        public void ReadBinary(object obj, IBinaryReader reader)
+        /** <inheritDoc /> */
+        public T1 ReadBinary<T1>(BinaryReader reader, Type type, int pos)
         {
-            throw new NotSupportedException("System serializer does not 
support ReadBinary.");
+            return TypeCaster<T1>.Cast(_ctor(reader));
         }
 
         /** <inheritdoc /> */
-        public object ReadInstance(BinaryReader reader)
+        public bool SupportsHandles
         {
-            return _ctor(reader);
+            get { return false; }
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
index 1ac98c4..fd5b2ee 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
@@ -1101,7 +1101,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                 var pos = _stream.Position;
 
                 // Dealing with handles.
-                if (!(desc.Serializer is IBinarySystemTypeSerializer) && 
WriteHandle(pos, obj))
+                if (desc.Serializer.SupportsHandles && WriteHandle(pos, obj))
                     return;
 
                 // Skip header length as not everything is known now

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs
new file mode 100644
index 0000000..bea7d58
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/DateTimeSerializer.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// DateTime serializer.
+    /// </summary>
+    internal class DateTimeSerializer : IBinarySerializerInternal
+    {
+        /** <inheritdoc /> */
+        public void WriteBinary<T>(T obj, BinaryWriter writer)
+        {
+            TypeCaster<DateTimeHolder>.Cast(obj).WriteBinary(writer);
+        }
+
+        /** <inheritdoc /> */
+        public T ReadBinary<T>(BinaryReader reader, Type type, int pos)
+        {
+            var holder = new DateTimeHolder(reader);
+
+            return TypeCaster<T>.Cast(holder.Item);
+        }
+
+        /** <inheritdoc /> */
+        public bool SupportsHandles
+        {
+            get { return false; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs
new file mode 100644
index 0000000..58844d6
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySerializerInternal.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+
+    /// <summary>
+    /// Internal generic serializer interface.
+    /// </summary>
+    internal interface IBinarySerializerInternal
+    {
+        /// <summary>
+        /// Write binary object.
+        /// </summary>
+        void WriteBinary<T>(T obj, BinaryWriter writer);
+
+        /// <summary>
+        /// Read binary object.
+        /// </summary>
+        T ReadBinary<T>(BinaryReader reader, Type type, int pos);
+
+        /// <summary>
+        /// Gets a value indicating whether this serializer supports handles.
+        /// </summary>
+        bool SupportsHandles { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySystemTypeSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySystemTypeSerializer.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySystemTypeSerializer.cs
deleted file mode 100644
index 3571ffb..0000000
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinarySystemTypeSerializer.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-namespace Apache.Ignite.Core.Impl.Binary
-{
-    using Apache.Ignite.Core.Binary;
-
-    /// <summary>
-    /// Serializer for system types that can create instances directly from a 
stream and does not support handles.
-    /// </summary>
-    internal interface IBinarySystemTypeSerializer : IBinarySerializer
-    {
-        /// <summary>
-        /// Reads the instance from a reader.
-        /// </summary>
-        /// <param name="reader">The reader.</param>
-        /// <returns>Deserialized instance.</returns>
-        object ReadInstance(BinaryReader reader);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs
index e50279c..e25d720 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryTypeDescriptor.cs
@@ -65,7 +65,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Serializer.
         /// </summary>
-        IBinarySerializer Serializer { get; }
+        IBinarySerializerInternal Serializer { get; }
 
         /// <summary>
         /// Affinity key field name.

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index aa881bb..5836b48 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -82,24 +82,19 @@ namespace Apache.Ignite.Core.Impl.Binary
             AddSystemTypes();
 
             // 2. Define user types.
-            var dfltSerializer = cfg.DefaultSerializer == null ? new 
BinaryReflectiveSerializer() : null;
-
             var typeResolver = new TypeResolver();
 
             ICollection<BinaryTypeConfiguration> typeCfgs = 
cfg.TypeConfigurations;
 
             if (typeCfgs != null)
                 foreach (BinaryTypeConfiguration typeCfg in typeCfgs)
-                    AddUserType(cfg, typeCfg, typeResolver, dfltSerializer);
+                    AddUserType(cfg, typeCfg, typeResolver);
 
             var typeNames = cfg.Types;
 
             if (typeNames != null)
                 foreach (string typeName in typeNames)
-                    AddUserType(cfg, new BinaryTypeConfiguration(typeName), 
typeResolver, dfltSerializer);
-
-            if (cfg.DefaultSerializer == null)
-                cfg.DefaultSerializer = dfltSerializer;
+                    AddUserType(cfg, new BinaryTypeConfiguration(typeName), 
typeResolver);
 
             _cfg = cfg;
         }
@@ -406,9 +401,8 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="cfg">Configuration.</param>
         /// <param name="typeCfg">Type configuration.</param>
         /// <param name="typeResolver">The type resolver.</param>
-        /// <param name="dfltSerializer">The default serializer.</param>
         private void AddUserType(BinaryConfiguration cfg, 
BinaryTypeConfiguration typeCfg, 
-            TypeResolver typeResolver, IBinarySerializer dfltSerializer)
+            TypeResolver typeResolver)
         {
             // Get converter/mapper/serializer.
             IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? 
cfg.DefaultNameMapper;
@@ -422,19 +416,6 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             if (type != null)
             {
-                // Type is found.
-                var typeName = BinaryUtils.GetTypeName(type);
-
-                int typeId = BinaryUtils.TypeId(typeName, nameMapper, 
idMapper);
-
-                var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer
-                                 ?? GetBinarizableSerializer(type) ?? 
dfltSerializer;
-
-                var refSerializer = serializer as BinaryReflectiveSerializer;
-
-                if (refSerializer != null)
-                    refSerializer.Register(type, typeId, nameMapper, idMapper);
-
                 if (typeCfg.IsEnum != type.IsEnum)
                     throw new BinaryObjectException(
                         string.Format(
@@ -442,7 +423,11 @@ namespace Apache.Ignite.Core.Impl.Binary
                             "Configuration value: IsEnum={0}, actual type: 
IsEnum={1}",
                             typeCfg.IsEnum, type.IsEnum));
 
+                // Type is found.
+                var typeName = BinaryUtils.GetTypeName(type);
+                int typeId = BinaryUtils.TypeId(typeName, nameMapper, 
idMapper);
                 var affKeyFld = typeCfg.AffinityKeyFieldName ?? 
GetAffinityKeyFieldNameFromAttribute(type);
+                var serializer = GetSerializer(cfg, typeCfg, type, typeId, 
nameMapper, idMapper);
 
                 AddType(type, typeId, typeName, true, keepDeserialized, 
nameMapper, idMapper, serializer,
                     affKeyFld, type.IsEnum);
@@ -460,6 +445,29 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Gets the serializer.
+        /// </summary>
+        private static IBinarySerializerInternal 
GetSerializer(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg,
+            Type type, int typeId, IBinaryNameMapper nameMapper, 
IBinaryIdMapper idMapper)
+        {
+            var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer;
+
+            if (serializer == null)
+            {
+                if (type.GetInterfaces().Contains(typeof(IBinarizable)))
+                    return BinarizableSerializer.Instance;
+
+                serializer = new BinaryReflectiveSerializer();
+            }
+
+            var refSerializer = serializer as BinaryReflectiveSerializer;
+
+            return refSerializer != null
+                ? refSerializer.Register(type, typeId, nameMapper, idMapper)
+                : new UserSerializerProxy(serializer);
+        }
+
+        /// <summary>
         /// Gets the affinity key field name from attribute.
         /// </summary>
         private static string GetAffinityKeyFieldNameFromAttribute(Type type)
@@ -478,18 +486,6 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
-        /// Gets the <see cref="BinarizableSerializer"/> for a type if it is 
compatible.
-        /// </summary>
-        /// <param name="type">The type.</param>
-        /// <returns>Resulting <see cref="BinarizableSerializer"/>, or 
null.</returns>
-        private static IBinarySerializer GetBinarizableSerializer(Type type)
-        {
-            return type.GetInterfaces().Contains(typeof (IBinarizable)) 
-                ? BinarizableSerializer.Instance 
-                : null;
-        }
-
-        /// <summary>
         /// Add type.
         /// </summary>
         /// <param name="type">Type.</param>
@@ -504,7 +500,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="isEnum">Enum flag.</param>
         private void AddType(Type type, int typeId, string typeName, bool 
userType, 
             bool keepDeserialized, IBinaryNameMapper nameMapper, 
IBinaryIdMapper idMapper,
-            IBinarySerializer serializer, string affKeyFieldName, bool isEnum)
+            IBinarySerializerInternal serializer, string affKeyFieldName, bool 
isEnum)
         {
             long typeKey = BinaryUtils.TypeKey(userType, typeId);
 
@@ -540,12 +536,13 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Adds a predefined system type.
         /// </summary>
-        private void AddSystemType<T>(int typeId, Func<BinaryReader, T> ctor, 
string affKeyFldName = null)
+        private void AddSystemType<T>(int typeId, Func<BinaryReader, T> ctor, 
string affKeyFldName = null, 
+            IBinarySerializerInternal serializer = null)
             where T : IBinaryWriteAware
         {
             var type = typeof(T);
 
-            var serializer = new BinarySystemTypeSerializer<T>(ctor);
+            serializer = serializer ?? new BinarySystemTypeSerializer<T>(ctor);
 
             if (typeId == 0)
                 typeId = BinaryUtils.TypeId(type.Name, null, null);
@@ -568,8 +565,10 @@ namespace Apache.Ignite.Core.Impl.Binary
             AddSystemType(BinaryUtils.TypeComputeFuncJob, w => new 
ComputeFuncJob(w));
             AddSystemType(BinaryUtils.TypeComputeActionJob, w => new 
ComputeActionJob(w));
             AddSystemType(BinaryUtils.TypeContinuousQueryRemoteFilterHolder, w 
=> new ContinuousQueryFilterHolder(w));
-            AddSystemType(BinaryUtils.TypeSerializableHolder, w => new 
SerializableObjectHolder(w));
-            AddSystemType(BinaryUtils.TypeDateTimeHolder, w => new 
DateTimeHolder(w));
+            AddSystemType(BinaryUtils.TypeSerializableHolder, w => new 
SerializableObjectHolder(w),
+                serializer: new SerializableSerializer());
+            AddSystemType(BinaryUtils.TypeDateTimeHolder, w => new 
DateTimeHolder(w),
+                serializer: new DateTimeSerializer());
             AddSystemType(BinaryUtils.TypeCacheEntryProcessorHolder, w => new 
CacheEntryProcessorHolder(w));
             AddSystemType(BinaryUtils.TypeCacheEntryPredicateHolder, w => new 
CacheEntryFilterHolder(w));
             AddSystemType(BinaryUtils.TypeMessageListenerHolder, w => new 
MessageListenerHolder(w));

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead2b1f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
new file mode 100644
index 0000000..55ac3c0
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Serializable serializer.
+    /// </summary>
+    internal class SerializableSerializer : IBinarySerializerInternal
+    {
+        /** <inheritdoc /> */
+        public void WriteBinary<T>(T obj, BinaryWriter writer)
+        {
+            TypeCaster<SerializableObjectHolder>.Cast(obj).WriteBinary(writer);
+        }
+
+        /** <inheritdoc /> */
+        public T ReadBinary<T>(BinaryReader reader, Type type, int pos)
+        {
+            var holder = new SerializableObjectHolder(reader);
+
+            return TypeCaster<T>.Cast(holder.Item);
+        }
+
+        /** <inheritdoc /> */
+        public bool SupportsHandles
+        {
+            get { return false; }
+        }
+    }
+}
\ No newline at end of file

Reply via email to