diff Source/Mapping/DictionaryListMapperT.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/DictionaryListMapperT.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using BLToolkit.Common;
+using BLToolkit.Reflection;
+
+namespace BLToolkit.Mapping
+{
+	public class DictionaryListMapper<K,T> : IMapDataDestinationList
+	{
+		public DictionaryListMapper(
+			IDictionary<K,T>     dic,
+			NameOrIndexParameter keyField,
+			ObjectMapper         objectMapper)
+		{
+			_dic        = dic;
+			_mapper     = objectMapper;
+			_keyGetter  = MapGetData<K>.I;
+			_fromSource = keyField.ByName && keyField.Name[0] == '@';
+			_keyField   = _fromSource? keyField.Name.Substring(1): keyField;
+		}
+
+		private readonly IDictionary<K,T>     _dic;
+		private readonly bool                 _fromSource;
+		private readonly MapGetData<K>.MB<K>  _keyGetter;
+		private          NameOrIndexParameter _keyField;
+		private          int                  _index;
+		private          ObjectMapper         _mapper;
+		private          object               _newObject;
+		private          bool                 _typeMismatch;
+		private          K                    _keyValue;
+
+		#region IMapDataDestinationList Members
+
+		private void AddObject()
+		{
+			if (_newObject != null)
+			{
+				if (_typeMismatch)
+					_keyValue = _mapper.MappingSchema.ConvertTo<K,object>(_mapper[_index].GetValue(_newObject));
+				else if (!_fromSource)
+					_keyValue = _keyGetter.From(_mapper, _newObject, _index);
+
+				_dic[_keyValue] = (T)_newObject;
+			}
+		}
+
+		public virtual void InitMapping(InitContext initContext)
+		{
+			var sm = _dic as ISupportMapping;
+
+			if (sm != null)
+			{
+				sm.BeginMapping(initContext);
+
+				if (_mapper != initContext.ObjectMapper)
+					_mapper = initContext.ObjectMapper;
+			}
+
+			if (_fromSource)
+				_index = _keyField.ByName? initContext.DataSource.GetOrdinal(_keyField.Name): _keyField.Index;
+			else
+			{
+				_index = _keyField.ByName? _mapper.GetOrdinal(_keyField.Name, true): _keyField.Index;
+
+				if (_index < 0)
+					throw new MappingException(
+						_keyField.ByName?
+						string.Format("Field '{0}' not found.", _keyField.Name):
+						string.Format("Index '{0}' is invalid.", _keyField.Index));
+
+				var mm = _mapper[_index];
+				_typeMismatch = !TypeHelper.IsSameOrParent(typeof(K), mm.Type);
+
+#if !SILVERLIGHT
+
+				Debug.WriteLineIf(_typeMismatch, string.Format(
+					"Member {0} type '{1}' does not match dictionary key type '{2}'.",
+						mm.Name, mm.Type.Name, (typeof(K).Name)));
+
+#endif
+			}
+		}
+
+		[CLSCompliant(false)]
+		public virtual IMapDataDestination GetDataDestination(InitContext initContext)
+		{
+			return _mapper;
+		}
+
+		static readonly char[] _trim = { ' ' };
+
+		public virtual object GetNextObject(InitContext initContext)
+		{
+			AddObject();
+
+			if (_fromSource)
+			{
+				_keyValue = _keyGetter.From(initContext.DataSource, initContext.SourceObject, _index);
+
+				if (Common.Configuration.TrimDictionaryKey && _keyValue is string)
+					_keyValue = (K)(object)_keyValue.ToString().TrimEnd(_trim);
+			}
+
+			return _newObject = _mapper.CreateInstance(initContext);
+		}
+
+		public virtual void EndMapping(InitContext initContext)
+		{
+			AddObject();
+
+			ISupportMapping sm = _dic as ISupportMapping;
+
+			if (sm != null)
+				sm.EndMapping(initContext);
+		}
+
+		#endregion
+	}
+}