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
+ using ServiceStack . Text . Common ;
8
+
9
+ namespace ServiceStack
10
+ {
11
+ public class TypeFields < T > : TypeFields
12
+ {
13
+ public static readonly TypeFields < T > Instance = new TypeFields < T > ( ) ;
14
+
15
+ public readonly Dictionary < string , SetPropertyDelegateRefGeneric < T > > GenericPublicSetters =
16
+ new Dictionary < string , SetPropertyDelegateRefGeneric < T > > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
17
+
18
+ static TypeFields ( )
19
+ {
20
+ Instance . Type = typeof ( T ) ;
21
+ Instance . PublicFieldInfos = typeof ( T ) . GetPublicFields ( ) ;
22
+ foreach ( var fi in Instance . PublicFieldInfos )
23
+ {
24
+ try
25
+ {
26
+ Instance . PublicGetters [ fi . Name ] = PclExport . Instance . GetFieldGetterFn ( fi ) ;
27
+ Instance . PublicSetters [ fi . Name ] = fi . GetValueSetter ( typeof ( T ) ) ;
28
+ Instance . GenericPublicSetters [ fi . Name ] = fi . GetValueSetterGenericRef < T > ( ) ;
29
+ Instance . PublicFields [ fi . Name ] = fi ;
30
+ }
31
+ catch ( Exception ex )
32
+ {
33
+ Tracer . Instance . WriteError ( ex ) ;
34
+ }
35
+ }
36
+ }
37
+
38
+ public override SetPropertyDelegateRef GetPublicSetterRef ( string name )
39
+ {
40
+ if ( name == null )
41
+ return null ;
42
+
43
+ return GenericPublicSetters . TryGetValue ( name , out SetPropertyDelegateRefGeneric < T > fn )
44
+ ? delegate ( ref object instance , object arg )
45
+ {
46
+ var valueInstance = ( T ) instance ;
47
+ fn ( ref valueInstance , arg ) ;
48
+ instance = valueInstance ;
49
+ }
50
+ : ( SetPropertyDelegateRef ) null ;
51
+ }
52
+ }
53
+
54
+ public abstract class TypeFields
55
+ {
56
+ static Dictionary < Type , TypeFields > CacheMap = new Dictionary < Type , TypeFields > ( ) ;
57
+
58
+ public static TypeFields Get ( Type type )
59
+ {
60
+ if ( CacheMap . TryGetValue ( type , out TypeFields value ) )
61
+ return value ;
62
+
63
+ var genericType = typeof ( TypeFields < > ) . MakeGenericType ( type ) ;
64
+ var instanceFi = genericType . GetPublicStaticField ( "Instance" ) ;
65
+ var instance = ( TypeFields ) instanceFi . GetValue ( null ) ;
66
+
67
+ Dictionary < Type , TypeFields > snapshot , newCache ;
68
+ do
69
+ {
70
+ snapshot = CacheMap ;
71
+ newCache = new Dictionary < Type , TypeFields > ( CacheMap ) {
72
+ [ type] = instance
73
+ } ;
74
+ } while ( ! ReferenceEquals (
75
+ Interlocked . CompareExchange ( ref CacheMap , newCache , snapshot ) , snapshot ) ) ;
76
+
77
+ return instance ;
78
+ }
79
+
80
+ public Type Type ;
81
+
82
+ public readonly Dictionary < string , PropertyGetterDelegate > PublicGetters =
83
+ new Dictionary < string , PropertyGetterDelegate > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
84
+
85
+ public readonly Dictionary < string , Action < object , object > > PublicSetters =
86
+ new Dictionary < string , Action < object , object > > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
87
+
88
+ public readonly Dictionary < string , FieldInfo > PublicFields =
89
+ new Dictionary < string , FieldInfo > ( PclExport . Instance . InvariantComparerIgnoreCase ) ;
90
+
91
+ public FieldInfo [ ] PublicFieldInfos { get ; protected set ; }
92
+
93
+ public virtual FieldInfo GetPublicField ( string name )
94
+ {
95
+ foreach ( var fi in PublicFieldInfos )
96
+ {
97
+ if ( fi . Name == name )
98
+ return fi ;
99
+ }
100
+ return null ;
101
+ }
102
+
103
+ public virtual PropertyGetterDelegate GetPublicGetter ( FieldInfo fi )
104
+ {
105
+ if ( fi == null )
106
+ return null ;
107
+
108
+ return PublicGetters . TryGetValue ( fi . Name , out PropertyGetterDelegate fn )
109
+ ? fn
110
+ : PclExport . Instance . GetFieldGetterFn ( fi ) ;
111
+ }
112
+
113
+ public virtual PropertyGetterDelegate GetPublicGetter ( string name )
114
+ {
115
+ if ( name == null )
116
+ return null ;
117
+
118
+ return PublicGetters . TryGetValue ( name , out PropertyGetterDelegate fn )
119
+ ? fn
120
+ : null ;
121
+ }
122
+
123
+ public virtual Action < object , object > GetPublicSetter ( FieldInfo fi )
124
+ {
125
+ if ( fi == null )
126
+ return null ;
127
+
128
+ return PublicSetters . TryGetValue ( fi . Name , out Action < object , object > fn )
129
+ ? fn
130
+ : fi . GetValueSetter ( Type ) ;
131
+ }
132
+
133
+ public virtual Action < object , object > GetPublicSetter ( string name )
134
+ {
135
+ if ( name == null )
136
+ return null ;
137
+
138
+ return PublicSetters . TryGetValue ( name , out Action < object , object > fn )
139
+ ? fn
140
+ : null ;
141
+ }
142
+
143
+ public virtual SetPropertyDelegateRef GetPublicSetterRef ( string name )
144
+ {
145
+ throw new NotImplementedException ( ) ;
146
+ }
147
+ }
148
+ }
0 commit comments