Business Logic Toolkit for .NET
www.bltoolkit.net
|  Home   |  Download   |  Documentation   |  Discussions   |  License   |

  Source.Mapping.DictionaryListMapperT.cs

 
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)
        {
            ISupportMapping 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));

                MemberMapper mm = _mapper[_index];
                _typeMismatch = !TypeHelper.IsSameOrParent(typeof(K), mm.Type);

                Debug.WriteLineIf(_typeMismatch, string.Format(
                    "Member {0} type '{1}' does not match dictionary key type '{2}'.",
                        mm.Name, mm.Type.Name, (typeof(K).Name)));
            }
        }

        [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
    }
}
 
© 2010 www.bltoolkit.net
support@bltoolkit.net