diff Source/Mapping/ValueMapping.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Mapping/ValueMapping.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,155 @@
+using System;
+
+using BLToolkit.Common;
+
+using KeyValue = System.Collections.Generic.KeyValuePair<System.Type, System.Type>;
+using Table    = System.Collections.Generic.Dictionary<System.Collections.Generic.KeyValuePair<System.Type, System.Type>, BLToolkit.Mapping.IValueMapper>;
+
+namespace BLToolkit.Mapping
+{
+	public static class ValueMapping
+	{
+		#region Init
+
+		private static readonly Table _mappers = new Table();
+
+		#endregion
+
+		#region Default Mapper
+
+		class DefaultValueMapper : IValueMapper
+		{
+			public void Map(
+				IMapDataSource      source, object sourceObject, int sourceIndex,
+				IMapDataDestination dest,   object destObject,   int destIndex)
+			{
+				dest.SetValue(destObject, destIndex, source.GetValue(sourceObject, sourceIndex));
+
+				//object o = source.GetValue(sourceObject, sourceIndex);
+
+				//if (o == null) dest.SetNull (destObject, destIndex);
+				//else           dest.SetValue(destObject, destIndex, o);
+			}
+		}
+
+		private static IValueMapper _defaultMapper = new DefaultValueMapper();
+		[CLSCompliant(false)]
+		public  static IValueMapper  DefaultMapper
+		{
+			get { return _defaultMapper;  }
+			set { _defaultMapper = value; }
+		}
+
+		#endregion
+
+		#region GetMapper
+
+		private static readonly object _sync = new object();
+
+		[CLSCompliant(false)]
+		public static IValueMapper GetMapper(Type t1, Type t2)
+		{
+			if (t1 == null) t1 = typeof(object);
+			if (t2 == null) t2 = typeof(object);
+
+			if (t1.IsEnum) t1 = Enum.GetUnderlyingType(t1);
+			if (t2.IsEnum) t2 = Enum.GetUnderlyingType(t2);
+
+			var key = new KeyValue(t1, t2);
+
+			lock (_sync)
+			{
+				IValueMapper t;
+
+				if (_mappers.TryGetValue(key, out t))
+					return t;
+
+				//t = BLToolkit.Mapping.ValueMappingInternal.MapperSelector.GetMapper(t1, t2);
+
+				if (null == t)
+				{
+					var type = typeof(GetSetDataChecker<,>).MakeGenericType(t1, t2);
+
+					if (((IGetSetDataChecker)Activator.CreateInstance(type)).Check() == false)
+					{
+						t = _defaultMapper;
+					}
+					else
+					{
+						type = t1 == t2 ?
+							typeof(ValueMapper<>).MakeGenericType(t1) :
+							typeof(ValueMapper<,>).MakeGenericType(t1, t2);
+
+						t = (IValueMapper)Activator.CreateInstance(type);
+					}
+				}
+
+				_mappers.Add(key, t);
+
+				return t;
+			}
+		}
+
+		#endregion
+
+		#region Generic Mappers
+
+		interface IGetSetDataChecker
+		{
+			bool Check();
+		}
+
+		class GetSetDataChecker<S,D> : IGetSetDataChecker
+		{
+			public bool Check()
+			{
+				return
+					!(MapGetData<S>.I is MapGetData<S>.Default<S>) &&
+					!(MapSetData<S>.I is MapSetData<S>.Default<S>) &&
+					!(MapGetData<D>.I is MapGetData<D>.Default<D>) &&
+					!(MapSetData<D>.I is MapSetData<D>.Default<D>);
+			}
+		}
+
+		class ValueMapper<T> : IValueMapper
+		{
+			public void Map(
+				IMapDataSource      source, object sourceObject, int sourceIndex,
+				IMapDataDestination dest,   object destObject,   int destIndex)
+			{
+				if (source.IsNull(sourceObject, sourceIndex))
+					dest.SetNull(destObject, destIndex);
+				else
+				{
+					var setter = MapSetData<T>.I;
+					var getter = MapGetData<T>.I;
+
+					setter.To(dest, destObject, destIndex,
+						getter.From(source, sourceObject, sourceIndex));
+				}
+			}
+		}
+
+		class ValueMapper<S,D> : IValueMapper
+		{
+			public void Map(
+				IMapDataSource      source, object sourceObject, int sourceIndex,
+				IMapDataDestination dest,   object destObject,   int destIndex)
+			{
+				if (source.IsNull(sourceObject, sourceIndex))
+					dest.SetNull(destObject, destIndex);
+				else
+				{
+					var setter    = MapSetData<D>.I;
+					var getter    = MapGetData<S>.I;
+					var converter = Convert<D,S>.From;
+
+					setter.To(dest, destObject, destIndex,
+						converter(getter.From(source, sourceObject, sourceIndex)));
+				}
+			}
+		}
+
+		#endregion
+	}
+}