ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject [20/45] ignite git commit: IGNITE-1348: Moved GridGain's .Net module to Ignite.
Date Sat, 05 Sep 2015 02:32:03 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
new file mode 100644
index 0000000..c44a0a4
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -0,0 +1,1305 @@
+/*
+ * 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.Portable
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using Apache.Ignite.Core.Impl.Portable.IO;
+    using Apache.Ignite.Core.Impl.Portable.Metadata;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Portable writer implementation.
+    /// </summary>
+    internal class PortableWriterImpl : IPortableWriter, IPortableRawWriter
+    {
+        /** Marshaller. */
+        private readonly PortableMarshaller _marsh;
+
+        /** Stream. */
+        private readonly IPortableStream _stream;
+
+        /** Builder (used only during build). */
+        private PortableBuilderImpl _builder;
+
+        /** Handles. */
+        private PortableHandleDictionary<object, long> _hnds;
+
+        /** Metadatas collected during this write session. */
+        private IDictionary<int, IPortableMetadata> _metas;
+
+        /** Current type ID. */
+        private int _curTypeId;
+
+        /** Current name converter */
+        private IPortableNameMapper _curConverter;
+
+        /** Current mapper. */
+        private IPortableIdMapper _curMapper;
+
+        /** Current metadata handler. */
+        private IPortableMetadataHandler _curMetaHnd;
+
+        /** Current raw flag. */
+        private bool _curRaw;
+
+        /** Current raw position. */
+        private long _curRawPos;
+
+        /** Ignore handles flag. */
+        private bool _detach;
+
+        /** Object started ignore mode. */
+        private bool _detachMode;
+
+        /// <summary>
+        /// Gets the marshaller.
+        /// </summary>
+        internal PortableMarshaller Marshaller
+        {
+            get { return _marsh; }
+        }
+
+        /// <summary>
+        /// Write named boolean value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Boolean value.</param>
+        public void WriteBoolean(string fieldName, bool val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeBool, val, PortableSystemHandlers.WriteHndBoolTyped, 1);
+        }
+        
+        /// <summary>
+        /// Write boolean value.
+        /// </summary>
+        /// <param name="val">Boolean value.</param>
+        public void WriteBoolean(bool val)
+        {
+            _stream.WriteBool(val);
+        }
+
+        /// <summary>
+        /// Write named boolean array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Boolean array.</param>
+        public void WriteBooleanArray(string fieldName, bool[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayBool, val,
+                PortableSystemHandlers.WriteHndBoolArrayTyped, val != null ? val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write boolean array.
+        /// </summary>
+        /// <param name="val">Boolean array.</param>
+        public void WriteBooleanArray(bool[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndBoolArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named byte value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Byte value.</param>
+        public void WriteByte(string fieldName, byte val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeByte, val, PortableSystemHandlers.WriteHndByteTyped, 1);
+        }
+
+        /// <summary>
+        /// Write byte value.
+        /// </summary>
+        /// <param name="val">Byte value.</param>
+        public void WriteByte(byte val)
+        {
+            _stream.WriteByte(val);
+        }
+
+        /// <summary>
+        /// Write named byte array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Byte array.</param>
+        public void WriteByteArray(string fieldName, byte[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayByte, val,
+                PortableSystemHandlers.WriteHndByteArrayTyped, val != null ? val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write byte array.
+        /// </summary>
+        /// <param name="val">Byte array.</param>
+        public void WriteByteArray(byte[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndByteArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named short value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Short value.</param>
+        public void WriteShort(string fieldName, short val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeShort, val, PortableSystemHandlers.WriteHndShortTyped, 2);
+        }
+
+        /// <summary>
+        /// Write short value.
+        /// </summary>
+        /// <param name="val">Short value.</param>
+        public void WriteShort(short val)
+        {
+            _stream.WriteShort(val);
+        }
+
+        /// <summary>
+        /// Write named short array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Short array.</param>
+        public void WriteShortArray(string fieldName, short[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayShort, val,
+                PortableSystemHandlers.WriteHndShortArrayTyped, val != null ? 2 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write short array.
+        /// </summary>
+        /// <param name="val">Short array.</param>
+        public void WriteShortArray(short[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndShortArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named char value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Char value.</param>
+        public void WriteChar(string fieldName, char val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeChar, val, PortableSystemHandlers.WriteHndCharTyped, 2);
+        }
+
+        /// <summary>
+        /// Write char value.
+        /// </summary>
+        /// <param name="val">Char value.</param>
+        public void WriteChar(char val)
+        {
+            _stream.WriteChar(val);
+        }
+
+        /// <summary>
+        /// Write named char array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Char array.</param>
+        public void WriteCharArray(string fieldName, char[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayChar, val,
+                PortableSystemHandlers.WriteHndCharArrayTyped, val != null ? 2 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write char array.
+        /// </summary>
+        /// <param name="val">Char array.</param>
+        public void WriteCharArray(char[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndCharArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named int value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Int value.</param>
+        public void WriteInt(string fieldName, int val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeInt, val, PortableSystemHandlers.WriteHndIntTyped, 4);
+        }
+
+        /// <summary>
+        /// Write int value.
+        /// </summary>
+        /// <param name="val">Int value.</param>
+        public void WriteInt(int val)
+        {
+            _stream.WriteInt(val);
+        }
+
+        /// <summary>
+        /// Write named int array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Int array.</param>
+        public void WriteIntArray(string fieldName, int[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayInt, val,
+                PortableSystemHandlers.WriteHndIntArrayTyped, val != null ? 4 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write int array.
+        /// </summary>
+        /// <param name="val">Int array.</param>
+        public void WriteIntArray(int[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndIntArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named long value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Long value.</param>
+        public void WriteLong(string fieldName, long val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeLong, val, PortableSystemHandlers.WriteHndLongTyped, 8);
+        }
+
+        /// <summary>
+        /// Write long value.
+        /// </summary>
+        /// <param name="val">Long value.</param>
+        public void WriteLong(long val)
+        {
+            _stream.WriteLong(val);
+        }
+
+        /// <summary>
+        /// Write named long array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Long array.</param>
+        public void WriteLongArray(string fieldName, long[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayLong, val,
+                PortableSystemHandlers.WriteHndLongArrayTyped, val != null ? 8 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write long array.
+        /// </summary>
+        /// <param name="val">Long array.</param>
+        public void WriteLongArray(long[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndLongArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named float value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Float value.</param>
+        public void WriteFloat(string fieldName, float val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeFloat, val, PortableSystemHandlers.WriteHndFloatTyped, 4);
+        }
+
+        /// <summary>
+        /// Write float value.
+        /// </summary>
+        /// <param name="val">Float value.</param>
+        public void WriteFloat(float val)
+        {
+            _stream.WriteFloat(val);
+        }
+
+        /// <summary>
+        /// Write named float array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Float array.</param>
+        public void WriteFloatArray(string fieldName, float[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayFloat, val,
+                PortableSystemHandlers.WriteHndFloatArrayTyped, val != null ? 4 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write float array.
+        /// </summary>
+        /// <param name="val">Float array.</param>
+        public void WriteFloatArray(float[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndFloatArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named double value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Double value.</param>
+        public void WriteDouble(string fieldName, double val)
+        {
+            WriteSimpleField(fieldName, PortableUtils.TypeDouble, val, PortableSystemHandlers.WriteHndDoubleTyped, 8);
+        }
+
+        /// <summary>
+        /// Write double value.
+        /// </summary>
+        /// <param name="val">Double value.</param>
+        public void WriteDouble(double val)
+        {
+            _stream.WriteDouble(val);
+        }
+
+        /// <summary>
+        /// Write named double array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Double array.</param>
+        public void WriteDoubleArray(string fieldName, double[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDouble, val,
+                PortableSystemHandlers.WriteHndDoubleArrayTyped, val != null ? 8 * val.Length + 4 : 0);
+        }
+
+        /// <summary>
+        /// Write double array.
+        /// </summary>
+        /// <param name="val">Double array.</param>
+        public void WriteDoubleArray(double[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDoubleArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named decimal value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Decimal value.</param>
+        public void WriteDecimal(string fieldName, decimal val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeDecimal, val, PortableSystemHandlers.WriteHndDecimalTyped);
+        }
+
+        /// <summary>
+        /// Write decimal value.
+        /// </summary>
+        /// <param name="val">Decimal value.</param>
+        public void WriteDecimal(decimal val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDecimalTyped);
+        }
+
+        /// <summary>
+        /// Write named decimal array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Decimal array.</param>
+        public void WriteDecimalArray(string fieldName, decimal[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDecimal, val,
+                PortableSystemHandlers.WriteHndDecimalArrayTyped);
+        }
+        
+        /// <summary>
+        /// Write decimal array.
+        /// </summary>
+        /// <param name="val">Decimal array.</param>
+        public void WriteDecimalArray(decimal[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDecimalArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named date value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Date value.</param>
+        public void WriteDate(string fieldName, DateTime? val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeDate, val, PortableSystemHandlers.WriteHndDateTyped,
+                val.HasValue ? 12 : 0);
+        }
+        
+        /// <summary>
+        /// Write date value.
+        /// </summary>
+        /// <param name="val">Date value.</param>
+        public void WriteDate(DateTime? val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDateTyped);
+        }
+
+        /// <summary>
+        /// Write named date array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Date array.</param>
+        public void WriteDateArray(string fieldName, DateTime?[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDate, val,
+                PortableSystemHandlers.WriteHndDateArrayTyped);
+        }
+
+        /// <summary>
+        /// Write date array.
+        /// </summary>
+        /// <param name="val">Date array.</param>
+        public void WriteDateArray(DateTime?[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDateArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named string value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">String value.</param>
+        public void WriteString(string fieldName, string val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeString, val, PortableSystemHandlers.WriteHndStringTyped);
+        }
+
+        /// <summary>
+        /// Write string value.
+        /// </summary>
+        /// <param name="val">String value.</param>
+        public void WriteString(string val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndStringTyped);
+        }
+
+        /// <summary>
+        /// Write named string array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">String array.</param>
+        public void WriteStringArray(string fieldName, string[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayString, val,
+                PortableSystemHandlers.WriteHndStringArrayTyped);
+        }
+
+        /// <summary>
+        /// Write string array.
+        /// </summary>
+        /// <param name="val">String array.</param>
+        public void WriteStringArray(string[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndStringArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named GUID value.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">GUID value.</param>
+        public void WriteGuid(string fieldName, Guid? val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeGuid, val, PortableSystemHandlers.WriteHndGuidTyped,
+                val.HasValue ? 16 : 0);
+        }
+
+        /// <summary>
+        /// Write GUID value.
+        /// </summary>
+        /// <param name="val">GUID value.</param>
+        public void WriteGuid(Guid? val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndGuidTyped);
+        }
+
+        /// <summary>
+        /// Write named GUID array.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">GUID array.</param>
+        public void WriteGuidArray(string fieldName, Guid?[] val)
+        {
+            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayGuid, val,
+                PortableSystemHandlers.WriteHndGuidArrayTyped);
+        }
+
+        /// <summary>
+        /// Write GUID array.
+        /// </summary>
+        /// <param name="val">GUID array.</param>
+        public void WriteGuidArray(Guid?[] val)
+        {
+            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndGuidArrayTyped);
+        }
+
+        /// <summary>
+        /// Write named enum value.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Enum value.</param>
+        public void WriteEnum<T>(string fieldName, T val)
+        {
+            WriteField(fieldName, PortableUtils.TypeEnum, val, PortableSystemHandlers.WriteHndEnum);
+        }
+
+        /// <summary>
+        /// Write enum value.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="val">Enum value.</param>
+        public void WriteEnum<T>(T val)
+        {
+            Write(val, PortableSystemHandlers.WriteHndEnum);
+        }
+
+        /// <summary>
+        /// Write named enum array.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Enum array.</param>
+        public void WriteEnumArray<T>(string fieldName, T[] val)
+        {
+            WriteField(fieldName, PortableUtils.TypeArrayEnum, val, PortableSystemHandlers.WriteHndEnumArray);
+        }
+
+        /// <summary>
+        /// Write enum array.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="val">Enum array.</param>
+        public void WriteEnumArray<T>(T[] val)
+        {
+            Write(val, PortableSystemHandlers.WriteHndEnumArray);
+        }
+
+        /// <summary>
+        /// Write named object value.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Object value.</param>
+        public void WriteObject<T>(string fieldName, T val)
+        {
+            WriteField(fieldName, PortableUtils.TypeObject, val, null);
+        }
+
+        /// <summary>
+        /// Write object value.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="val">Object value.</param>
+        public void WriteObject<T>(T val)
+        {
+            Write(val);
+        }
+
+        /// <summary>
+        /// Write named object array.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Object array.</param>
+        public void WriteObjectArray<T>(string fieldName, T[] val)
+        {
+            WriteField(fieldName, PortableUtils.TypeArray, val, PortableSystemHandlers.WriteHndArray);
+        }
+
+        /// <summary>
+        /// Write object array.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="val">Object array.</param>
+        public void WriteObjectArray<T>(T[] val)
+        {
+            Write(val, PortableSystemHandlers.WriteHndArray);
+        }
+
+        /// <summary>
+        /// Write named collection.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Collection.</param>
+        public void WriteCollection(string fieldName, ICollection val)
+        {
+            WriteField(fieldName, PortableUtils.TypeCollection, val, null);
+        }
+
+        /// <summary>
+        /// Write collection.
+        /// </summary>
+        /// <param name="val">Collection.</param>
+        public void WriteCollection(ICollection val)
+        {
+            Write(val);
+        }
+
+        /// <summary>
+        /// Write named generic collection.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Collection.</param>
+        public void WriteGenericCollection<T>(string fieldName, ICollection<T> val)
+        {
+            WriteField(fieldName, PortableUtils.TypeCollection, val, null);
+        }
+
+        /// <summary>
+        /// Write generic collection.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="val">Collection.</param>
+        public void WriteGenericCollection<T>(ICollection<T> val)
+        {
+            Write(val);
+        }
+
+        /// <summary>
+        /// Write named dictionary.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Dictionary.</param>
+        public void WriteDictionary(string fieldName, IDictionary val)
+        {
+            WriteField(fieldName, PortableUtils.TypeDictionary, val, null);
+        }
+
+        /// <summary>
+        /// Write dictionary.
+        /// </summary>
+        /// <param name="val">Dictionary.</param>
+        public void WriteDictionary(IDictionary val)
+        {
+            Write(val);
+        }
+
+        /// <summary>
+        /// Write named generic dictionary.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="val">Dictionary.</param>
+        public void WriteGenericDictionary<TK, TV>(string fieldName, IDictionary<TK, TV> val)
+        {
+            WriteField(fieldName, PortableUtils.TypeDictionary, val, null);
+        }
+
+        /// <summary>
+        /// Write generic dictionary.
+        /// </summary>
+        /// <param name="val">Dictionary.</param>
+        public void WriteGenericDictionary<TK, TV>(IDictionary<TK, TV> val)
+        {
+            Write(val);
+        }
+
+        /// <summary>
+        /// Get raw writer.
+        /// </summary>
+        /// <returns>
+        /// Raw writer.
+        /// </returns>
+        public IPortableRawWriter RawWriter()
+        {
+            if (!_curRaw)
+            {
+                _curRaw = true;
+                _curRawPos = _stream.Position;
+            }
+
+            return this;
+        }
+
+        /// <summary>
+        /// Set new builder.
+        /// </summary>
+        /// <param name="builder">Builder.</param>
+        /// <returns>Previous builder.</returns>
+        internal PortableBuilderImpl Builder(PortableBuilderImpl builder)
+        {
+            PortableBuilderImpl ret = _builder;
+
+            _builder = builder;
+
+            return ret;
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="marsh">Marshaller.</param>
+        /// <param name="stream">Stream.</param>
+        internal PortableWriterImpl(PortableMarshaller marsh, IPortableStream stream)
+        {
+            _marsh = marsh;
+            _stream = stream;
+        }
+
+        /// <summary>
+        /// Write object.
+        /// </summary>
+        /// <param name="obj">Object.</param>
+        internal void Write<T>(T obj)
+        {
+            Write(obj, null);
+        }
+
+        /// <summary>
+        /// Write object.
+        /// </summary>
+        /// <param name="obj">Object.</param>
+        /// <param name="handler">Optional write handler.</param>
+        [SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
+        internal void Write<T>(T obj, object handler)
+        {
+            // Apply detach mode if needed.
+            PortableHandleDictionary<object, long> oldHnds = null;
+
+            bool resetDetach = false;
+
+            if (_detach)
+            {
+                _detach = false;
+                _detachMode = true;
+                resetDetach = true;
+
+                oldHnds = _hnds;
+
+                _hnds = null;
+            }
+
+            try
+            {
+                // Write null.
+                if (obj == null)
+                {
+                    _stream.WriteByte(PortableUtils.HdrNull);
+
+                    return;
+                }
+
+                if (_builder != null)
+                {
+                    // Special case for portable object during build.
+                    PortableUserObject portObj = obj as PortableUserObject;
+
+                    if (portObj != null)
+                    {
+                        if (!WriteHandle(_stream.Position, portObj))
+                            _builder.ProcessPortable(_stream, portObj);
+
+                        return;
+                    }
+
+                    // Special case for builder during build.
+                    PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
+
+                    if (portBuilder != null)
+                    {
+                        if (!WriteHandle(_stream.Position, portBuilder))
+                            _builder.ProcessBuilder(_stream, portBuilder);
+
+                        return;
+                    }
+                }                
+
+                // Try writting as well-known type.
+                if (InvokeHandler(handler, handler as PortableSystemWriteDelegate, obj))
+                    return;
+
+                Type type = obj.GetType();
+
+                IPortableTypeDescriptor desc = _marsh.Descriptor(type);
+
+                object typedHandler;
+                PortableSystemWriteDelegate untypedHandler;
+
+                if (desc == null)
+                {
+                    typedHandler = null;
+                    untypedHandler = PortableSystemHandlers.WriteHandler(type);
+                }
+                else
+                {
+                    typedHandler = desc.TypedHandler;
+                    untypedHandler = desc.UntypedHandler;
+                }
+
+                if (InvokeHandler(typedHandler, untypedHandler, obj))
+                    return;
+
+                if (desc == null)
+                {
+                    if (!type.IsSerializable)
+                        // If neither handler, nor descriptor exist, and not serializable, this is an exception.
+                        throw new PortableException("Unsupported object type [type=" + type +
+                            ", object=" + obj + ']');
+
+                    Write(new SerializableObjectHolder(obj));
+
+                    return;
+                }
+
+                int pos = _stream.Position;
+
+                // Dealing with handles.
+                if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
+                    return;
+
+                // Write header.
+                _stream.WriteByte(PortableUtils.HdrFull);
+
+                _stream.WriteBool(desc.UserType);
+                _stream.WriteInt(desc.TypeId);
+                _stream.WriteInt(obj.GetHashCode());
+
+                // Skip length as it is not known in the first place.
+                _stream.Seek(8, SeekOrigin.Current);
+
+                // Preserve old frame.
+                int oldTypeId = _curTypeId;
+                IPortableNameMapper oldConverter = _curConverter;
+                IPortableIdMapper oldMapper = _curMapper;
+                IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
+                bool oldRaw = _curRaw;
+                long oldRawPos = _curRawPos;
+
+                // Push new frame.
+                _curTypeId = desc.TypeId;
+                _curConverter = desc.NameConverter;
+                _curMapper = desc.Mapper;
+                _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
+                _curRaw = false;
+                _curRawPos = 0;
+
+                // Write object fields.
+                desc.Serializer.WritePortable(obj, this);
+
+                // Calculate and write length.
+                int retPos = _stream.Position;
+
+                _stream.Seek(pos + 10, SeekOrigin.Begin);
+
+                int len = retPos - pos;
+
+                _stream.WriteInt(len);
+
+                if (_curRawPos != 0)
+                    // When set, it is difference between object head and raw position.
+                    _stream.WriteInt((int)(_curRawPos - pos));
+                else
+                    // When no set, it is equal to object length.
+                    _stream.WriteInt(len);
+
+                _stream.Seek(retPos, SeekOrigin.Begin);
+
+                // 13. Collect metadata.
+                if (_curMetaHnd != null)
+                {
+                    IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
+
+                    if (meta != null)
+                        SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+                }
+
+                // Restore old frame.
+                _curTypeId = oldTypeId;
+                _curConverter = oldConverter;
+                _curMapper = oldMapper;
+                _curMetaHnd = oldMetaHnd;
+                _curRaw = oldRaw;
+                _curRawPos = oldRawPos;
+            }
+            finally
+            {
+                // Restore handles if needed.
+                if (resetDetach)
+                {
+                    // Add newly recorded handles without overriding already existing ones.
+                    if (_hnds != null)
+                    {
+                        if (oldHnds == null)
+                            oldHnds = _hnds;
+                        else
+                            oldHnds.Merge(_hnds);
+                    }
+
+                    _hnds = oldHnds;
+
+                    _detachMode = false;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Add handle to handles map.
+        /// </summary>
+        /// <param name="pos">Position in stream.</param>
+        /// <param name="obj">Object.</param>
+        /// <returns><c>true</c> if object was written as handle.</returns>
+        private bool WriteHandle(long pos, object obj)
+        {
+            if (_hnds == null)
+            {
+                // Cache absolute handle position.
+                _hnds = new PortableHandleDictionary<object, long>(obj, pos);
+
+                return false;
+            }
+
+            long hndPos;
+
+            if (!_hnds.TryGetValue(obj, out hndPos))
+            {
+                // Cache absolute handle position.
+                _hnds.Add(obj, pos);
+
+                return false;
+            }
+
+            _stream.WriteByte(PortableUtils.HdrHnd);
+
+            // Handle is written as difference between position before header and handle position.
+            _stream.WriteInt((int)(pos - hndPos));
+
+            return true;
+        }
+
+        /// <summary>
+        /// Try invoking predefined handler on object.
+        /// </summary>
+        /// <param name="typedHandler">Handler</param>
+        /// <param name="untypedHandler">Not typed handler.</param>
+        /// <param name="obj">Object.</param>
+        /// <returns>True if handler was called.</returns>
+        private bool InvokeHandler<T>(object typedHandler, PortableSystemWriteDelegate untypedHandler, T obj)
+        {
+            var typedHandler0 = typedHandler as PortableSystemTypedWriteDelegate<T>;
+
+            if (typedHandler0 != null)
+            {
+                typedHandler0.Invoke(_stream, obj);
+
+                return true;
+            }
+
+            if (untypedHandler != null)
+            {
+                untypedHandler.Invoke(this, obj);
+
+                return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Write simple field with known length.
+        /// </summary>
+        /// <param name="fieldId">Field ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        /// <param name="len">Length.</param>
+        private void WriteSimpleField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler, int len)
+        {
+            CheckNotRaw();
+
+            _stream.WriteInt(fieldId);
+            _stream.WriteInt(1 + len); // Additional byte for field type.
+
+            handler(_stream, val);
+        }
+
+        /// <summary>
+        /// Write simple nullable field with unknown length.
+        /// </summary>
+        /// <param name="fieldId">Field ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        private void WriteSimpleNullableField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler)
+        {
+            CheckNotRaw();
+
+            _stream.WriteInt(fieldId);
+
+            if (val == null)
+            {
+                _stream.WriteInt(1);
+
+                _stream.WriteByte(PortableUtils.HdrNull);
+            }
+            else
+            {
+                int pos = _stream.Position;
+
+                _stream.Seek(4, SeekOrigin.Current);
+
+                handler(_stream, val);
+
+                WriteFieldLength(_stream, pos);
+            }
+        }
+
+        /// <summary>
+        /// Write simple nullable field with known length.
+        /// </summary>
+        /// <param name="fieldId">Field ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        /// <param name="len">Length.</param>
+        private void WriteSimpleNullableField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler, int len)
+        {
+            CheckNotRaw();
+
+            _stream.WriteInt(fieldId);
+
+            if (val == null)
+            {
+                _stream.WriteInt(1);
+
+                _stream.WriteByte(PortableUtils.HdrNull);
+            }
+            else
+            {
+                _stream.WriteInt(1 + len);
+
+                handler(_stream, val);
+            }
+        }
+
+        /// <summary>
+        /// Write field.
+        /// </summary>
+        /// <param name="fieldId">Field ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        private void WriteField(int fieldId, object val, PortableSystemWriteDelegate handler)
+        {
+            CheckNotRaw();
+
+            _stream.WriteInt(fieldId);
+
+            int pos = _stream.Position;
+
+            _stream.Seek(4, SeekOrigin.Current);
+
+            Write(val, handler);
+
+            WriteFieldLength(_stream, pos);
+        }
+
+        /// <summary>
+        /// Enable detach mode for the next object.
+        /// </summary>
+        internal void DetachNext()
+        {
+            if (!_detachMode)
+                _detach = true;
+        }
+
+        /// <summary>
+        /// Stream.
+        /// </summary>
+        internal IPortableStream Stream
+        {
+            get { return _stream; }
+        }
+
+        /// <summary>
+        /// Gets collected metadatas.
+        /// </summary>
+        /// <returns>Collected metadatas (if any).</returns>
+        internal IDictionary<int, IPortableMetadata> Metadata()
+        {
+            return _metas;
+        }
+
+        /// <summary>
+        /// Check whether the given object is portable, i.e. it can be 
+        /// serialized with portable marshaller.
+        /// </summary>
+        /// <param name="obj">Object.</param>
+        /// <returns>True if portable.</returns>
+        internal bool IsPortable(object obj)
+        {
+            if (obj != null)
+            {
+                Type type = obj.GetType();
+
+                // We assume object as portable only in case it has descriptor.
+                // Collections, Enums and non-primitive arrays do not have descriptors
+                // and this is fine here because we cannot know whether their members
+                // are portable.
+                return _marsh.Descriptor(type) != null;
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Write simple field with known length.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        /// <param name="len">Length.</param>
+        private void WriteSimpleField<T>(string fieldName, byte typeId, T val,
+            PortableSystemTypedWriteDelegate<T> handler, int len)
+        {
+            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+            WriteSimpleField(fieldId, val, handler, len);
+
+            if (_curMetaHnd != null)
+                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+        }
+
+        /// <summary>
+        /// Write simple nullable field with unknown length.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        private void WriteSimpleNullableField<T>(string fieldName, byte typeId, T val,
+            PortableSystemTypedWriteDelegate<T> handler)
+        {
+            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+            WriteSimpleNullableField(fieldId, val, handler);
+
+            if (_curMetaHnd != null)
+                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+        }
+
+        /// <summary>
+        /// Write simple nullable field with known length.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        /// <param name="len">Length.</param>
+        private void WriteSimpleNullableField<T>(string fieldName, byte typeId, T val,
+            PortableSystemTypedWriteDelegate<T> handler, int len)
+        {
+            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+            WriteSimpleNullableField(fieldId, val, handler, len);
+
+            if (_curMetaHnd != null)
+                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+        }
+
+        /// <summary>
+        /// Write nullable raw field.
+        /// </summary>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        private void WriteSimpleNullableRawField<T>(T val, PortableSystemTypedWriteDelegate<T> handler)
+        {
+            if (val == null)
+                _stream.WriteByte(PortableUtils.HdrNull);
+            else
+                handler(_stream, val);
+        }
+
+        /// <summary>
+        /// Write field.
+        /// </summary>
+        /// <param name="fieldName">Field name.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="val">Value.</param>
+        /// <param name="handler">Handler.</param>
+        private void WriteField(string fieldName, byte typeId, object val,
+            PortableSystemWriteDelegate handler)
+        {
+            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+
+            WriteField(fieldId, val, handler);
+
+            if (_curMetaHnd != null)
+                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+        }
+
+        /// <summary>
+        /// Write field length.
+        /// </summary>
+        /// <param name="stream">Stream.</param>
+        /// <param name="pos">Position where length should reside</param>
+        private static void WriteFieldLength(IPortableStream stream, int pos)
+        {
+            int retPos = stream.Position;
+
+            stream.Seek(pos, SeekOrigin.Begin);
+
+            stream.WriteInt(retPos - pos - 4);
+
+            stream.Seek(retPos, SeekOrigin.Begin);
+        }
+
+        /// <summary>
+        /// Ensure that we are not in raw mode.
+        /// </summary>
+        private void CheckNotRaw()
+        {
+            if (_curRaw)
+                throw new PortableException("Cannot write named fields after raw data is written.");
+        }
+
+        /// <summary>
+        /// Saves metadata for this session.
+        /// </summary>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="typeName">Type name.</param>
+        /// <param name="affKeyFieldName">Affinity key field name.</param>
+        /// <param name="fields">Fields metadata.</param>
+        internal void SaveMetadata(int typeId, string typeName, string affKeyFieldName, IDictionary<string, int> fields)
+        {
+            if (_metas == null)
+            {
+                PortableMetadataImpl meta =
+                    new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName);
+
+                _metas = new Dictionary<int, IPortableMetadata>(1);
+
+                _metas[typeId] = meta;
+            }
+            else
+            {
+                IPortableMetadata meta;
+
+                if (_metas.TryGetValue(typeId, out meta))
+                {
+                    IDictionary<string, int> existingFields = ((PortableMetadataImpl)meta).FieldsMap();
+
+                    foreach (KeyValuePair<string, int> field in fields)
+                    {
+                        if (!existingFields.ContainsKey(field.Key))
+                            existingFields[field.Key] = field.Value;
+                    }
+                }
+                else
+                    _metas[typeId] = new PortableMetadataImpl(typeId, typeName, fields, affKeyFieldName);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
new file mode 100644
index 0000000..066f46b
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
@@ -0,0 +1,205 @@
+/*
+ * 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.Portable
+{
+    using System;
+    using System.Collections.Generic;
+    using System.IO;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Impl.Portable.IO;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Portables implementation.
+    /// </summary>
+    internal class PortablesImpl : IPortables
+    {
+        /** Owning grid. */
+        private readonly PortableMarshaller _marsh;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="marsh">Marshaller.</param>
+        internal PortablesImpl(PortableMarshaller marsh)
+        {
+            _marsh = marsh;
+        }
+
+        /** <inheritDoc /> */
+        public T ToPortable<T>(object obj)
+        {
+            if (obj is IPortableObject)
+                return (T)obj;
+
+            IPortableStream stream = new PortableHeapStream(1024);
+
+            // Serialize.
+            PortableWriterImpl writer = _marsh.StartMarshal(stream);
+
+            try
+            {
+                writer.Write(obj);
+            }
+            finally
+            {
+                // Save metadata.
+                _marsh.FinishMarshal(writer);
+            }
+
+            // Deserialize.
+            stream.Seek(0, SeekOrigin.Begin);
+
+            return _marsh.Unmarshal<T>(stream, PortableMode.ForcePortable);
+        }
+
+        /** <inheritDoc /> */
+        public IPortableBuilder Builder(Type type)
+        {
+            IgniteArgumentCheck.NotNull(type, "type");
+
+            IPortableTypeDescriptor desc = _marsh.Descriptor(type);
+
+            if (desc == null)
+                throw new IgniteException("Type is not portable (add it to PortableConfiguration): " + 
+                    type.FullName);
+
+            return Builder0(null, PortableFromDescriptor(desc), desc);
+        }
+
+        /** <inheritDoc /> */
+        public IPortableBuilder Builder(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            IPortableTypeDescriptor desc = _marsh.Descriptor(typeName);
+            
+            return Builder0(null, PortableFromDescriptor(desc), desc);
+        }
+
+        /** <inheritDoc /> */
+        public IPortableBuilder Builder(IPortableObject obj)
+        {
+            IgniteArgumentCheck.NotNull(obj, "obj");
+
+            PortableUserObject obj0 = obj as PortableUserObject;
+
+            if (obj0 == null)
+                throw new ArgumentException("Unsupported object type: " + obj.GetType());
+
+            IPortableTypeDescriptor desc = _marsh.Descriptor(true, obj0.TypeId());
+            
+            return Builder0(null, obj0, desc);
+        }
+
+        /** <inheritDoc /> */
+        public int GetTypeId(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            return Marshaller.Descriptor(typeName).TypeId;
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<IPortableMetadata> GetMetadata()
+        {
+            return Marshaller.Ignite.ClusterGroup.Metadata();
+        }
+
+        /** <inheritDoc /> */
+        public IPortableMetadata GetMetadata(int typeId)
+        {
+            return Marshaller.Metadata(typeId);
+        }
+
+        /** <inheritDoc /> */
+        public IPortableMetadata GetMetadata(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            return GetMetadata(GetTypeId(typeName));
+        }
+
+        /** <inheritDoc /> */
+        public IPortableMetadata GetMetadata(Type type)
+        {
+            IgniteArgumentCheck.NotNull(type, "type");
+
+            var desc = Marshaller.Descriptor(type);
+
+            return desc == null ? null : Marshaller.Metadata(desc.TypeId);
+        }
+
+        /// <summary>
+        /// Create child builder.
+        /// </summary>
+        /// <param name="parent">Parent builder.</param>
+        /// <param name="obj">Portable object.</param>
+        /// <returns></returns>
+        internal PortableBuilderImpl ChildBuilder(PortableBuilderImpl parent, PortableUserObject obj)
+        {
+            IPortableTypeDescriptor desc = _marsh.Descriptor(true, obj.TypeId());
+
+            return Builder0(null, obj, desc);
+        }
+
+        /// <summary>
+        /// Marshaller.
+        /// </summary>
+        internal PortableMarshaller Marshaller
+        {
+            get
+            {
+                return _marsh;
+            }
+        }
+
+        /// <summary>
+        /// Create empty portable object from descriptor.
+        /// </summary>
+        /// <param name="desc">Descriptor.</param>
+        /// <returns>Empty portable object.</returns>
+        private PortableUserObject PortableFromDescriptor(IPortableTypeDescriptor desc)
+        {
+            PortableHeapStream stream = new PortableHeapStream(18);
+
+            stream.WriteByte(PortableUtils.HdrFull);
+            stream.WriteBool(true);
+            stream.WriteInt(desc.TypeId);
+            stream.WriteInt(0); // Hash.
+            stream.WriteInt(PortableUtils.FullHdrLen); // Length.
+            stream.WriteInt(PortableUtils.FullHdrLen); // Raw data offset.
+
+            return new PortableUserObject(_marsh, stream.InternalArray, 0, desc.TypeId, 0);
+        }
+
+        /// <summary>
+        /// Internal builder creation routine.
+        /// </summary>
+        /// <param name="parent">Parent builder.</param>
+        /// <param name="obj">Portable object.</param>
+        /// <param name="desc">Type descriptor.</param>
+        /// <returns>Builder.</returns>
+        private PortableBuilderImpl Builder0(PortableBuilderImpl parent, PortableUserObject obj, 
+            IPortableTypeDescriptor desc)
+        {
+            return new PortableBuilderImpl(this, parent, obj, desc);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
new file mode 100644
index 0000000..a3a9fe7
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
@@ -0,0 +1,66 @@
+/*
+ * 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.Portable
+{
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Wraps Serializable item in a portable.
+    /// </summary>
+    internal class SerializableObjectHolder : IPortableWriteAware
+    {
+        /** */
+        private readonly object _item;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SerializableObjectHolder"/> class.
+        /// </summary>
+        /// <param name="item">The item to wrap.</param>
+        public SerializableObjectHolder(object item)
+        {
+            _item = item;
+        }
+
+        /// <summary>
+        /// Gets the item to wrap.
+        /// </summary>
+        public object Item
+        {
+            get { return _item; }
+        }
+
+        /** <inheritDoc /> */
+        public void WritePortable(IPortableWriter writer)
+        {
+            var writer0 = (PortableWriterImpl)writer.RawWriter();
+
+            writer0.DetachNext();
+
+            PortableUtils.WriteSerializable(writer0, Item);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SerializableObjectHolder"/> class.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        public SerializableObjectHolder(IPortableReader reader)
+        {
+            _item = PortableUtils.ReadSerializable<object>((PortableReaderImpl)reader.RawReader());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/TypeResolver.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/TypeResolver.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/TypeResolver.cs
new file mode 100644
index 0000000..0785f4a
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/TypeResolver.cs
@@ -0,0 +1,227 @@
+/*
+ * 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.Portable
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Reflection;
+    using System.Text.RegularExpressions;
+
+    /// <summary>
+    /// Resolves types by name.
+    /// </summary>
+    internal class TypeResolver
+    {
+        /** Regex to parse generic types from portable configuration. Allows nested generics in type arguments. */
+        private static readonly Regex GenericTypeRegex =
+            new Regex(@"([^`,\[\]]*)(?:`[0-9]+)?(?:\[((?:(?<br>\[)|(?<-br>\])|[^\[\]]*)+)\])?", RegexOptions.Compiled);
+
+        /** Assemblies loaded in ReflectionOnly mode. */
+        private readonly Dictionary<string, Assembly> _reflectionOnlyAssemblies = new Dictionary<string, Assembly>();
+
+        /// <summary>
+        /// Resolve type by name.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="assemblyName">Optional, name of the assembly.</param>
+        /// <returns>
+        /// Resolved type.
+        /// </returns>
+        public Type ResolveType(string typeName, string assemblyName = null)
+        {
+            Debug.Assert(!string.IsNullOrEmpty(typeName));
+
+            return ResolveType(assemblyName, typeName, AppDomain.CurrentDomain.GetAssemblies())
+                ?? ResolveTypeInReferencedAssemblies(assemblyName, typeName);
+        }
+
+        /// <summary>
+        /// Resolve type by name in specified assembly set.
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly.</param>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="assemblies">Assemblies to look in.</param>
+        /// <returns> 
+        /// Resolved type. 
+        /// </returns>
+        private static Type ResolveType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
+        {
+            return ResolveGenericType(assemblyName, typeName, assemblies) ??
+                   ResolveNonGenericType(assemblyName, typeName, assemblies);
+        }
+
+        /// <summary>
+        /// Resolves non-generic type by searching provided assemblies.
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly.</param>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="assemblies">The assemblies.</param>
+        /// <returns>Resolved type, or null.</returns>
+        private static Type ResolveNonGenericType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
+        {
+            if (!string.IsNullOrEmpty(assemblyName))
+                assemblies = assemblies
+                    .Where(x => x.FullName == assemblyName || x.GetName().Name == assemblyName).ToArray();
+
+            if (!assemblies.Any())
+                return null;
+
+            // Trim assembly qualification
+            var commaIdx = typeName.IndexOf(',');
+
+            if (commaIdx > 0)
+                typeName = typeName.Substring(0, commaIdx);
+
+            return assemblies.Select(a => a.GetType(typeName, false, false)).FirstOrDefault(type => type != null);
+        }
+
+        /// <summary>
+        /// Resolves the name of the generic type by resolving each generic arg separately 
+        /// and substituting it's fully qualified name.
+        /// (Assembly.GetType finds generic types only when arguments are fully qualified).
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly.</param>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="assemblies">Assemblies</param>
+        /// <returns>Fully qualified generic type name, or null if argument(s) could not be resolved.</returns>
+        private static Type ResolveGenericType(string assemblyName, string typeName, ICollection<Assembly> assemblies)
+        {
+            var match = GenericTypeRegex.Match(typeName);
+
+            if (!match.Success || !match.Groups[2].Success)
+                return null;
+
+            // Try to construct generic type; each generic arg can also be a generic type.
+            var genericArgs = GenericTypeRegex.Matches(match.Groups[2].Value)
+                .OfType<Match>().Select(m => m.Value).Where(v => !string.IsNullOrWhiteSpace(v))
+                .Select(v => ResolveType(null, TrimBrackets(v), assemblies)).ToArray();
+
+            if (genericArgs.Any(x => x == null))
+                return null;
+
+            var genericType = ResolveNonGenericType(assemblyName,
+                string.Format("{0}`{1}", match.Groups[1].Value, genericArgs.Length), assemblies);
+
+            if (genericType == null)
+                return null;
+
+            return genericType.MakeGenericType(genericArgs);
+        }
+
+        /// <summary>
+        /// Trims the brackets from generic type arg.
+        /// </summary>
+        private static string TrimBrackets(string s)
+        {
+            return s.StartsWith("[") && s.EndsWith("]") ? s.Substring(1, s.Length - 2) : s;
+        }
+
+        /// <summary>
+        /// Resolve type by name in non-loaded referenced assemblies.
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly.</param>
+        /// <param name="typeName">Name of the type.</param>
+        /// <returns>
+        /// Resolved type.
+        /// </returns>
+        private Type ResolveTypeInReferencedAssemblies(string assemblyName, string typeName)
+        {
+            ResolveEventHandler resolver = (sender, args) => GetReflectionOnlyAssembly(args.Name);
+
+            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += resolver;
+
+            try
+            {
+                var result = ResolveType(assemblyName, typeName, GetNotLoadedReferencedAssemblies().ToArray());
+
+                if (result == null)
+                    return null;
+
+                // result is from ReflectionOnly assembly, load it properly into current domain
+                var asm = AppDomain.CurrentDomain.Load(result.Assembly.GetName());
+
+                return asm.GetType(result.FullName);
+            }
+            finally
+            {
+                AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= resolver;
+            }
+        }
+
+        /// <summary>
+        /// Gets the reflection only assembly.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+        private Assembly GetReflectionOnlyAssembly(string fullName)
+        {
+            Assembly result;
+
+            if (!_reflectionOnlyAssemblies.TryGetValue(fullName, out result))
+            {
+                try
+                {
+                    result = Assembly.ReflectionOnlyLoad(fullName);
+                }
+                catch (Exception)
+                {
+                    // Some assemblies may fail to load
+                    result = null;
+                }
+
+                _reflectionOnlyAssemblies[fullName] = result;
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// Recursively gets all referenced assemblies for current app domain, excluding those that are loaded.
+        /// </summary>
+        private IEnumerable<Assembly> GetNotLoadedReferencedAssemblies()
+        {
+            var roots = new Stack<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
+
+            var visited = new HashSet<string>();
+
+            var loaded = new HashSet<string>(roots.Select(x => x.FullName));
+
+            while (roots.Any())
+            {
+                var asm = roots.Pop();
+
+                if (visited.Contains(asm.FullName))
+                    continue;
+
+                if (!loaded.Contains(asm.FullName))
+                    yield return asm;
+
+                visited.Add(asm.FullName);
+
+                foreach (var refAsm in asm.GetReferencedAssemblies()
+                    .Where(x => !visited.Contains(x.FullName))
+                    .Where(x => !loaded.Contains(x.FullName))
+                    .Select(x => GetReflectionOnlyAssembly(x.FullName))
+                    .Where(x => x != null))
+                    roots.Push(refAsm);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/IResourceInjector.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/IResourceInjector.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/IResourceInjector.cs
new file mode 100644
index 0000000..b751680
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/IResourceInjector.cs
@@ -0,0 +1,27 @@
+/*
+ * 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.Resource
+{
+    /// <summary>
+    /// Resource injector interface.
+    /// </summary>
+    internal interface IResourceInjector
+    {
+        void Inject(object target, object val);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceFieldInjector.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceFieldInjector.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceFieldInjector.cs
new file mode 100644
index 0000000..d48db1f
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceFieldInjector.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.Resource
+{
+    using System;
+    using System.Reflection;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Field resource injector.
+    /// </summary>
+    internal class ResourceFieldInjector : IResourceInjector
+    {
+        /** */
+        private readonly Action<object, object> _inject;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="field">Field.</param>
+        public ResourceFieldInjector(FieldInfo field)
+        {
+            _inject = DelegateConverter.CompileFieldSetter(field);
+        }
+
+        /** <inheritDoc /> */
+        public void Inject(object target, object val)
+        {
+            _inject(target, val);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceMethodInjector.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceMethodInjector.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceMethodInjector.cs
new file mode 100644
index 0000000..9a7d9d3
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceMethodInjector.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.Resource
+{
+    using System;
+    using System.Reflection;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Method resource injector.
+    /// </summary>
+    internal class ResourceMethodInjector : IResourceInjector
+    {
+        /** */
+        private readonly Action<object, object> _inject;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="mthd">Method.</param>
+        public ResourceMethodInjector(MethodInfo mthd)
+        {
+            _inject = DelegateConverter.CompileFunc<Action<object, object>>(mthd.DeclaringType, mthd,
+                new[] {mthd.GetParameters()[0].ParameterType}, new[] {true, false});
+        }
+
+        /** <inheritDoc /> */
+        public void Inject(object target, object val)
+        {
+            _inject(target, val);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceProcessor.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceProcessor.cs
new file mode 100644
index 0000000..0a41d8c
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourceProcessor.cs
@@ -0,0 +1,105 @@
+/*
+ * 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.Resource
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Cache.Store;
+
+    /// <summary>
+    /// Resource processor.
+    /// </summary>
+    internal class ResourceProcessor
+    {
+        /** Mutex. */
+        private static readonly object Mux = new object();
+        
+        /** Cached descriptors. */
+        private static volatile IDictionary<Type, ResourceTypeDescriptor> _descs = 
+            new Dictionary<Type, ResourceTypeDescriptor>();
+
+        /// <summary>
+        /// Get descriptor for the given type.
+        /// </summary>
+        /// <param name="type">Type.</param>
+        /// <returns></returns>
+        public static ResourceTypeDescriptor Descriptor(Type type)
+        {
+            IDictionary<Type, ResourceTypeDescriptor> descs0 = _descs;
+
+            ResourceTypeDescriptor desc;
+
+            if (!descs0.TryGetValue(type, out desc))
+            {
+                lock (Mux)
+                {
+                    if (!_descs.TryGetValue(type, out desc))
+                    {
+                        // Create descriptor from scratch.
+                        desc = new ResourceTypeDescriptor(type);
+
+                        descs0 = new Dictionary<Type, ResourceTypeDescriptor>(_descs);
+
+                        descs0[type] = desc;
+
+                        _descs = descs0;
+                    }
+                }
+            }
+
+            return desc;
+        }
+
+        /// <summary>
+        /// Inject resources to the given target.
+        /// </summary>
+        /// <param name="target">Target object.</param>
+        /// <param name="grid">Grid.</param>
+        public static void Inject(object target, Ignite grid)
+        {
+            Inject(target, grid.Proxy);
+        }
+
+        /// <summary>
+        /// Inject resources to the given target.
+        /// </summary>
+        /// <param name="target">Target object.</param>
+        /// <param name="grid">Grid.</param>
+        public static void Inject(object target, IgniteProxy grid)
+        {
+            if (target != null) {
+                var desc = Descriptor(target.GetType());
+    
+                desc.InjectIgnite(target, grid);
+            }
+        }
+
+        /// <summary>
+        /// Inject cache store session.
+        /// </summary>
+        /// <param name="store">Store.</param>
+        /// <param name="ses">Store session.</param>
+        public static void InjectStoreSession(ICacheStore store, ICacheStoreSession ses)
+        {
+            Debug.Assert(store != null);
+
+            Descriptor(store.GetType()).InjectStoreSession(store, ses);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourcePropertyInjector.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourcePropertyInjector.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourcePropertyInjector.cs
new file mode 100644
index 0000000..05e2c2d
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Resource/ResourcePropertyInjector.cs
@@ -0,0 +1,47 @@
+/*
+ * 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.Resource
+{
+    using System;
+    using System.Reflection;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Property resource injector.
+    /// </summary>
+    internal class ResourcePropertyInjector : IResourceInjector
+    {
+        /** */
+        private readonly Action<object, object> _inject;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="prop">Property.</param>
+        public ResourcePropertyInjector(PropertyInfo prop)
+        {
+            _inject = DelegateConverter.CompilePropertySetter(prop);
+        }
+
+        /** <inheritDoc /> */
+        public void Inject(object target, object val)
+        {
+            _inject(target, val);
+        }
+    }
+}


Mime
View raw message