FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
ServiceStack/src/ServiceStack.Common/TypeExtensions.cs at master · csharpbuilder/ServiceStack · GitHub
csharpbuilder
/
ServiceStack
Public
forked from
ServiceStack/ServiceStack
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
ServiceStack
/
src
/
ServiceStack.Common
/
TypeExtensions.cs
Copy path
More file actions
More file actions
Latest commit
History
History
History
204 lines (165 loc) · 7.18 KB
Breadcrumbs
ServiceStack
/
src
/
ServiceStack.Common
/
TypeExtensions.cs
Copy path
File metadata and controls
204 lines (165 loc) · 7.18 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
using
System
;
using
System
.
Collections
.
Generic
;
using
System
.
Linq
.
Expressions
;
using
System
.
Reflection
;
using
System
.
Threading
;
namespace
ServiceStack
{
public
delegate
object
ObjectActivator
(
params
object
[
]
args
)
;
public
delegate
object
MethodInvoker
(
object
instance
,
params
object
[
]
args
)
;
public
static
class
TypeExtensions
{
public
static
Type
[
]
GetReferencedTypes
(
this
Type
type
)
{
var
refTypes
=
new
HashSet
<
Type
>
{
type
}
;
AddReferencedTypes
(
type
,
refTypes
)
;
return
refTypes
.
ToArray
(
)
;
}
public
static
void
AddReferencedTypes
(
Type
type
,
HashSet
<
Type
>
refTypes
)
{
if
(
type
.
BaseType
!=
null
)
{
if
(
!
refTypes
.
Contains
(
type
.
BaseType
)
)
{
refTypes
.
Add
(
type
.
BaseType
)
;
AddReferencedTypes
(
type
.
BaseType
,
refTypes
)
;
}
if
(
!
type
.
BaseType
.
GetGenericArguments
(
)
.
IsEmpty
(
)
)
{
foreach
(
var
arg
in
type
.
BaseType
.
GetGenericArguments
(
)
)
{
if
(
!
refTypes
.
Contains
(
arg
)
)
{
refTypes
.
Add
(
arg
)
;
AddReferencedTypes
(
arg
,
refTypes
)
;
}
}
}
}
var
properties
=
type
.
GetProperties
(
)
;
if
(
!
properties
.
IsEmpty
(
)
)
{
foreach
(
var
p
in
properties
)
{
if
(
!
refTypes
.
Contains
(
p
.
PropertyType
)
)
{
refTypes
.
Add
(
p
.
PropertyType
)
;
AddReferencedTypes
(
type
,
refTypes
)
;
}
var
args
=
p
.
PropertyType
.
GetGenericArguments
(
)
;
if
(
!
args
.
IsEmpty
(
)
)
{
foreach
(
var
arg
in
args
)
{
if
(
!
refTypes
.
Contains
(
arg
)
)
{
refTypes
.
Add
(
arg
)
;
AddReferencedTypes
(
arg
,
refTypes
)
;
}
}
}
else
if
(
p
.
PropertyType
.
IsArray
)
{
var
elType
=
p
.
PropertyType
.
GetElementType
(
)
;
if
(
!
refTypes
.
Contains
(
elType
)
)
{
refTypes
.
Add
(
elType
)
;
AddReferencedTypes
(
elType
,
refTypes
)
;
}
}
}
}
}
public
static
ObjectActivator
GetActivatorToCache
(
ConstructorInfo
ctor
)
{
var
pi
=
ctor
.
GetParameters
(
)
;
var
paramArgs
=
Expression
.
Parameter
(
typeof
(
object
[
]
)
,
"args"
)
;
var
exprArgs
=
new
Expression
[
pi
.
Length
]
;
var
convertFromMethod
=
typeof
(
TypeExtensions
)
.
GetStaticMethod
(
nameof
(
ConvertFromObject
)
)
;
for
(
int
i
=
0
;
i
<
pi
.
Length
;
i
++
)
{
var
index
=
Expression
.
Constant
(
i
)
;
var
paramType
=
pi
[
i
]
.
ParameterType
;
var
paramAccessorExp
=
Expression
.
ArrayIndex
(
paramArgs
,
index
)
;
var
paramCastExp
=
Expression
.
Convert
(
paramAccessorExp
,
paramType
)
;
var
convertParam
=
convertFromMethod
.
MakeGenericMethod
(
paramType
)
;
exprArgs
[
i
]
=
Expression
.
Call
(
convertParam
,
paramAccessorExp
)
;
}
var
newExp
=
Expression
.
New
(
ctor
,
exprArgs
)
;
var
lambda
=
Expression
.
Lambda
(
typeof
(
ObjectActivator
)
,
newExp
,
paramArgs
)
;
var
ctorFn
=
(
ObjectActivator
)
lambda
.
Compile
(
)
;
return
ctorFn
;
}
static
Dictionary
<
ConstructorInfo
,
ObjectActivator
>
activatorCache
=
new
Dictionary
<
ConstructorInfo
,
ObjectActivator
>
(
)
;
public
static
ObjectActivator
GetActivator
(
this
ConstructorInfo
ctor
)
{
if
(
activatorCache
.
TryGetValue
(
ctor
,
out
var
fn
)
)
return
fn
;
fn
=
GetActivatorToCache
(
ctor
)
;
Dictionary
<
ConstructorInfo
,
ObjectActivator
>
snapshot
,
newCache
;
do
{
snapshot
=
activatorCache
;
newCache
=
new
Dictionary
<
ConstructorInfo
,
ObjectActivator
>
(
activatorCache
)
{
[
ctor
]
=
fn
}
;
}
while
(
!
ReferenceEquals
(
Interlocked
.
CompareExchange
(
ref
activatorCache
,
newCache
,
snapshot
)
,
snapshot
)
)
;
return
fn
;
}
public
static
MethodInvoker
GetInvokerToCache
(
MethodInfo
method
)
{
var
pi
=
method
.
GetParameters
(
)
;
var
paramInstance
=
Expression
.
Parameter
(
typeof
(
object
)
,
"instance"
)
;
var
paramArgs
=
Expression
.
Parameter
(
typeof
(
object
[
]
)
,
"args"
)
;
var
convertFromMethod
=
typeof
(
TypeExtensions
)
.
GetStaticMethod
(
nameof
(
ConvertFromObject
)
)
;
var
exprArgs
=
new
Expression
[
pi
.
Length
]
;
for
(
int
i
=
0
;
i
<
pi
.
Length
;
i
++
)
{
var
index
=
Expression
.
Constant
(
i
)
;
var
paramType
=
pi
[
i
]
.
ParameterType
;
var
paramAccessorExp
=
Expression
.
ArrayIndex
(
paramArgs
,
index
)
;
var
convertParam
=
convertFromMethod
.
MakeGenericMethod
(
paramType
)
;
exprArgs
[
i
]
=
Expression
.
Call
(
convertParam
,
paramAccessorExp
)
;
}
var
methodCall
=
Expression
.
Call
(
Expression
.
TypeAs
(
paramInstance
,
method
.
DeclaringType
)
,
method
,
exprArgs
)
;
var
convertToMethod
=
typeof
(
TypeExtensions
)
.
GetStaticMethod
(
nameof
(
ConvertToObject
)
)
;
var
convertReturn
=
convertToMethod
.
MakeGenericMethod
(
method
.
ReturnType
)
;
var
lambda
=
Expression
.
Lambda
(
typeof
(
MethodInvoker
)
,
Expression
.
Call
(
convertReturn
,
methodCall
)
,
paramInstance
,
paramArgs
)
;
var
fn
=
(
MethodInvoker
)
lambda
.
Compile
(
)
;
return
fn
;
}
static
Dictionary
<
MethodInfo
,
MethodInvoker
>
invokerCache
=
new
Dictionary
<
MethodInfo
,
MethodInvoker
>
(
)
;
public
static
MethodInvoker
GetInvoker
(
this
MethodInfo
method
)
{
if
(
invokerCache
.
TryGetValue
(
method
,
out
var
fn
)
)
return
fn
;
fn
=
GetInvokerToCache
(
method
)
;
Dictionary
<
MethodInfo
,
MethodInvoker
>
snapshot
,
newCache
;
do
{
snapshot
=
invokerCache
;
newCache
=
new
Dictionary
<
MethodInfo
,
MethodInvoker
>
(
invokerCache
)
{
[
method
]
=
fn
}
;
}
while
(
!
ReferenceEquals
(
Interlocked
.
CompareExchange
(
ref
invokerCache
,
newCache
,
snapshot
)
,
snapshot
)
)
;
return
fn
;
}
public
static
T
ConvertFromObject
<
T
>
(
object
value
)
{
if
(
value
==
null
)
return
default
(
T
)
;
if
(
value
is
T
variable
)
return
variable
;
if
(
typeof
(
T
)
==
typeof
(
string
)
&&
value
is
IRawString
rs
)
return
(
T
)
(
object
)
rs
.
ToRawString
(
)
;
return
value
.
ConvertTo
<
T
>
(
)
;
}
public
static
object
ConvertToObject
<
T
>
(
T
value
)
{
return
value
;
}
}
}
Back
|
FazBrowse Home
|
New Git URL