1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Reflection ;
4
+ using System . Threading ;
5
+ using ServiceStack . Reflection ;
6
+ using ServiceStack . Text ;
7
+
8
+ namespace ServiceStack
9
+ {
10
+ [ Obsolete ( "Use TypeProperties<T>.Instance" ) ]
11
+ public static class TypeReflector < T > { }
12
+
13
+ public class TypeProperties < T > : TypeProperties
14
+ {
15
+ public static readonly TypeProperties < T > Instance = new TypeProperties < T > ( ) ;
16
+
17
+ static TypeProperties ( )
18
+ {
19
+ Instance . Type = typeof ( T ) ;
20
+ Instance . PublicPropertyInfos = typeof ( T ) . GetPublicProperties ( ) ;
21
+ foreach ( var pi in Instance . PublicPropertyInfos )
22
+ {
23
+ try
24
+ {
25
+ Instance . PublicGetters [ pi . Name ] = pi . GetValueGetter ( typeof ( T ) ) ;
26
+ Instance . PublicSetters [ pi . Name ] = pi . GetValueSetter ( typeof ( T ) ) ;
27
+ Instance . PublicProperties [ pi . Name ] = pi ;
28
+ }
29
+ catch ( Exception ex )
30
+ {
31
+ Tracer . Instance . WriteError ( ex ) ;
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ public abstract class TypeProperties
38
+ {
39
+ static Dictionary < Type , TypeProperties > CacheMap = new Dictionary < Type , TypeProperties > ( ) ;
40
+
41
+ public static Type FactoryType = typeof ( TypeProperties < > ) ;
42
+
43
+ public static TypeProperties Get ( Type type )
44
+ {
45
+ if ( CacheMap . TryGetValue ( type , out TypeProperties value ) )
46
+ return value ;
47
+
48
+ var genericType = FactoryType . MakeGenericType ( type ) ;
49
+ var instanceFi = genericType . GetPublicStaticField ( "Instance" ) ;
50
+ var instance = ( TypeProperties ) instanceFi . GetValue ( null ) ;
51
+
52
+ Dictionary < Type , TypeProperties > snapshot , newCache ;
53
+ do
54
+ {
55
+ snapshot = CacheMap ;
56
+ newCache = new Dictionary < Type , TypeProperties > ( CacheMap )
57
+ {
58
+ [ type] = instance
59
+ } ;
60
+ } while ( ! ReferenceEquals (
61
+ Interlocked . CompareExchange ( ref CacheMap , newCache , snapshot ) , snapshot ) ) ;
62
+
63
+ return instance ;
64
+ }
65
+
66
+ public Type Type { get ; protected set ; }
67
+
68
+ public readonly Dictionary < string , Func < object , object > > PublicGetters =
69
+ new Dictionary < string , Func < object , object > > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
70
+
71
+ public readonly Dictionary < string , Action < object , object > > PublicSetters =
72
+ new Dictionary < string , Action < object , object > > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
73
+
74
+ public readonly Dictionary < string , PropertyInfo > PublicProperties =
75
+ new Dictionary < string , PropertyInfo > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
76
+
77
+ public PropertyInfo [ ] PublicPropertyInfos { get ; protected set ; }
78
+
79
+ public PropertyInfo GetPublicProperty ( string name )
80
+ {
81
+ foreach ( var pi in PublicPropertyInfos )
82
+ {
83
+ if ( pi . Name == name )
84
+ return pi ;
85
+ }
86
+ return null ;
87
+ }
88
+
89
+ public Func < object , object > GetPublicGetter ( PropertyInfo pi )
90
+ {
91
+ if ( pi == null )
92
+ return null ;
93
+
94
+ return PublicGetters . TryGetValue ( pi . Name , out Func < object , object > fn )
95
+ ? fn
96
+ : pi . GetValueGetter ( ) ;
97
+ }
98
+
99
+ public Func < object , object > GetPublicGetter ( string name )
100
+ {
101
+ if ( name == null )
102
+ return null ;
103
+
104
+ return PublicGetters . TryGetValue ( name , out Func < object , object > fn )
105
+ ? fn
106
+ : null ;
107
+ }
108
+
109
+ public Action < object , object > GetPublicSetter ( PropertyInfo pi )
110
+ {
111
+ if ( pi == null )
112
+ return null ;
113
+
114
+ return PublicSetters . TryGetValue ( pi . Name , out Action < object , object > fn )
115
+ ? fn
116
+ : pi . GetValueSetter ( ) ;
117
+ }
118
+
119
+ public Action < object , object > GetPublicSetter ( string name )
120
+ {
121
+ if ( name == null )
122
+ return null ;
123
+
124
+ return PublicSetters . TryGetValue ( name , out Action < object , object > fn )
125
+ ? fn
126
+ : null ;
127
+ }
128
+ }
129
+ }
0 commit comments