11namespace AgileObjects . AgileMapper . PerformanceTester . ConcreteMappers . ValueInjecter
22{
3+ using System ;
4+ using System . Collections ;
5+ using System . Collections . Generic ;
6+ using System . Linq ;
7+ using System . Reflection ;
38 using AbstractMappers ;
49 using Omu . ValueInjecter ;
10+ using Omu . ValueInjecter . Injections ;
511 using TestClasses ;
612
713 internal class ValueInjecterComplexTypeMapper : ComplexTypeMapperBase
814 {
915 public override void Initialise ( )
1016 {
17+ Mapper . AddMap < List < Foo > , List < Foo > > ( foos => foos != null ? Mapper . Map < List < Foo > > ( foos ) : new List < Foo > ( ) ) ;
1118 }
1219
1320 protected override Foo Clone ( Foo foo )
1421 {
15- return Mapper . Map < Foo > ( foo ) ;
22+ return ( Foo ) new Foo ( ) . InjectFrom < CloneInjection > ( foo ) ;
23+ }
24+
25+ public class CloneInjection : LoopInjection
26+ {
27+ protected override void Execute ( PropertyInfo sp , object source , object target )
28+ {
29+ var tp = target . GetType ( ) . GetProperty ( sp . Name ) ;
30+ if ( tp == null ) return ;
31+ var val = sp . GetValue ( source ) ;
32+
33+ tp . SetValue ( target , GetClone ( sp , val ) ) ;
34+ }
35+
36+ private static object GetClone ( PropertyInfo sp , object val )
37+ {
38+ if ( sp . PropertyType . IsValueType || sp . PropertyType == typeof ( string ) )
39+ {
40+ return val ;
41+ }
42+
43+ if ( sp . PropertyType . IsArray )
44+ {
45+ if ( val == null )
46+ {
47+ return Array . CreateInstance ( sp . PropertyType . GetElementType ( ) , 0 ) ;
48+ }
49+
50+ var arr = val as Array ;
51+ var arrClone = arr . Clone ( ) as Array ;
52+
53+ for ( int index = 0 ; index < arr . Length ; index ++ )
54+ {
55+ var a = arr . GetValue ( index ) ;
56+ if ( a . GetType ( ) . IsValueType || a is string ) continue ;
57+
58+ arrClone . SetValue ( Activator . CreateInstance ( a . GetType ( ) ) . InjectFrom < CloneInjection > ( a ) , index ) ;
59+ }
60+
61+ return arrClone ;
62+ }
63+
64+ if ( sp . PropertyType . IsGenericType )
65+ {
66+ //handle IEnumerable<> also ICollection<> IList<> List<>
67+ if ( sp . PropertyType . GetGenericTypeDefinition ( ) . GetInterfaces ( ) . Contains ( typeof ( IEnumerable ) ) )
68+ {
69+ var genericType = sp . PropertyType . GetGenericArguments ( ) [ 0 ] ;
70+ var listType = typeof ( List < > ) . MakeGenericType ( genericType ) ;
71+
72+ if ( val == null )
73+ {
74+ return Activator . CreateInstance ( listType ) ;
75+ }
76+
77+ var list = Activator . CreateInstance ( listType ) ;
78+
79+ var addMethod = listType . GetMethod ( "Add" ) ;
80+ foreach ( var o in val as IEnumerable )
81+ {
82+ var listItem = genericType . IsValueType || genericType == typeof ( string ) ? o : Activator . CreateInstance ( genericType ) . InjectFrom < CloneInjection > ( o ) ;
83+ addMethod . Invoke ( list , new [ ] { listItem } ) ;
84+ }
85+
86+ return list ;
87+ }
88+
89+ //unhandled generic type, you could also return null or throw
90+ return val ;
91+ }
92+
93+ if ( val == null )
94+ {
95+ return null ;
96+ }
97+
98+ //for simple object types create a new instace and apply the clone injection on it
99+ return Activator . CreateInstance ( sp . PropertyType )
100+ . InjectFrom < CloneInjection > ( val ) ;
101+ }
16102 }
17103 }
18104}
0 commit comments