0
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.Diagnostics;
|
|
4 using BLToolkit.Common;
|
|
5 using BLToolkit.Reflection;
|
|
6
|
|
7 namespace BLToolkit.Mapping
|
|
8 {
|
|
9 public class DictionaryListMapper<K,T> : IMapDataDestinationList
|
|
10 {
|
|
11 public DictionaryListMapper(
|
|
12 IDictionary<K,T> dic,
|
|
13 NameOrIndexParameter keyField,
|
|
14 ObjectMapper objectMapper)
|
|
15 {
|
|
16 _dic = dic;
|
|
17 _mapper = objectMapper;
|
|
18 _keyGetter = MapGetData<K>.I;
|
|
19 _fromSource = keyField.ByName && keyField.Name[0] == '@';
|
|
20 _keyField = _fromSource? keyField.Name.Substring(1): keyField;
|
|
21 }
|
|
22
|
|
23 private readonly IDictionary<K,T> _dic;
|
|
24 private readonly bool _fromSource;
|
|
25 private readonly MapGetData<K>.MB<K> _keyGetter;
|
|
26 private NameOrIndexParameter _keyField;
|
|
27 private int _index;
|
|
28 private ObjectMapper _mapper;
|
|
29 private object _newObject;
|
|
30 private bool _typeMismatch;
|
|
31 private K _keyValue;
|
|
32
|
|
33 #region IMapDataDestinationList Members
|
|
34
|
|
35 private void AddObject()
|
|
36 {
|
|
37 if (_newObject != null)
|
|
38 {
|
|
39 if (_typeMismatch)
|
|
40 _keyValue = _mapper.MappingSchema.ConvertTo<K,object>(_mapper[_index].GetValue(_newObject));
|
|
41 else if (!_fromSource)
|
|
42 _keyValue = _keyGetter.From(_mapper, _newObject, _index);
|
|
43
|
|
44 _dic[_keyValue] = (T)_newObject;
|
|
45 }
|
|
46 }
|
|
47
|
|
48 public virtual void InitMapping(InitContext initContext)
|
|
49 {
|
|
50 var sm = _dic as ISupportMapping;
|
|
51
|
|
52 if (sm != null)
|
|
53 {
|
|
54 sm.BeginMapping(initContext);
|
|
55
|
|
56 if (_mapper != initContext.ObjectMapper)
|
|
57 _mapper = initContext.ObjectMapper;
|
|
58 }
|
|
59
|
|
60 if (_fromSource)
|
|
61 _index = _keyField.ByName? initContext.DataSource.GetOrdinal(_keyField.Name): _keyField.Index;
|
|
62 else
|
|
63 {
|
|
64 _index = _keyField.ByName? _mapper.GetOrdinal(_keyField.Name, true): _keyField.Index;
|
|
65
|
|
66 if (_index < 0)
|
|
67 throw new MappingException(
|
|
68 _keyField.ByName?
|
|
69 string.Format("Field '{0}' not found.", _keyField.Name):
|
|
70 string.Format("Index '{0}' is invalid.", _keyField.Index));
|
|
71
|
|
72 var mm = _mapper[_index];
|
|
73 _typeMismatch = !TypeHelper.IsSameOrParent(typeof(K), mm.Type);
|
|
74
|
|
75 #if !SILVERLIGHT
|
|
76
|
|
77 Debug.WriteLineIf(_typeMismatch, string.Format(
|
|
78 "Member {0} type '{1}' does not match dictionary key type '{2}'.",
|
|
79 mm.Name, mm.Type.Name, (typeof(K).Name)));
|
|
80
|
|
81 #endif
|
|
82 }
|
|
83 }
|
|
84
|
|
85 [CLSCompliant(false)]
|
|
86 public virtual IMapDataDestination GetDataDestination(InitContext initContext)
|
|
87 {
|
|
88 return _mapper;
|
|
89 }
|
|
90
|
|
91 static readonly char[] _trim = { ' ' };
|
|
92
|
|
93 public virtual object GetNextObject(InitContext initContext)
|
|
94 {
|
|
95 AddObject();
|
|
96
|
|
97 if (_fromSource)
|
|
98 {
|
|
99 _keyValue = _keyGetter.From(initContext.DataSource, initContext.SourceObject, _index);
|
|
100
|
|
101 if (Common.Configuration.TrimDictionaryKey && _keyValue is string)
|
|
102 _keyValue = (K)(object)_keyValue.ToString().TrimEnd(_trim);
|
|
103 }
|
|
104
|
|
105 return _newObject = _mapper.CreateInstance(initContext);
|
|
106 }
|
|
107
|
|
108 public virtual void EndMapping(InitContext initContext)
|
|
109 {
|
|
110 AddObject();
|
|
111
|
|
112 ISupportMapping sm = _dic as ISupportMapping;
|
|
113
|
|
114 if (sm != null)
|
|
115 sm.EndMapping(initContext);
|
|
116 }
|
|
117
|
|
118 #endregion
|
|
119 }
|
|
120 }
|