@@ -29,24 +29,35 @@ public class ServiceContainer : ServiceContainerBase
29
29
{
30
30
private static readonly Type iServiceContainerType = typeof ( IServiceContainer ) ;
31
31
32
+ #if NET8_0_OR_GREATER
33
+ private static readonly Func < ServiceRegistration , Pair < ConstructorInvoker , ParameterInfo [ ] > > ConstructorFactory = serviceInfo => {
34
+ #else
32
35
private static readonly Func < ServiceRegistration , Pair < ConstructorInfo , ParameterInfo [ ] > > ConstructorFactory = serviceInfo => {
36
+ #endif
33
37
var mappedType = serviceInfo . MappedType ;
34
38
var ctor = (
35
39
from c in mappedType . GetConstructors ( )
36
40
where c . GetAttribute < ServiceConstructorAttribute > ( AttributeSearchOptions . InheritNone ) != null
37
41
select c
38
42
) . SingleOrDefault ( ) ?? mappedType . GetConstructor ( Array . Empty < Type > ( ) ) ;
39
43
var @params = ctor ? . GetParameters ( ) ;
40
- return new Pair < ConstructorInfo , ParameterInfo [ ] > ( ctor , @params ) ;
44
+ #if NET8_0_OR_GREATER
45
+ return new ( ctor is null ? null : ConstructorInvoker . Create ( ctor ) , @params ) ;
46
+ #else
47
+ return new ( ctor , @params ) ;
48
+ #endif
41
49
} ;
42
50
43
51
private readonly IReadOnlyDictionary < Key , List < ServiceRegistration > > types ;
44
52
45
53
private readonly ConcurrentDictionary < ServiceRegistration , Lazy < object > > instances =
46
54
new ConcurrentDictionary < ServiceRegistration , Lazy < object > > ( ) ;
47
55
48
- private readonly ConcurrentDictionary < ServiceRegistration , Pair < ConstructorInfo , ParameterInfo [ ] > > constructorCache =
49
- new ConcurrentDictionary < ServiceRegistration , Pair < ConstructorInfo , ParameterInfo [ ] > > ( ) ;
56
+ #if NET8_0_OR_GREATER
57
+ private readonly ConcurrentDictionary < ServiceRegistration , Pair < ConstructorInvoker , ParameterInfo [ ] > > constructorCache = new ( ) ;
58
+ #else
59
+ private readonly ConcurrentDictionary < ServiceRegistration , Pair < ConstructorInfo , ParameterInfo [ ] > > constructorCache = new ( ) ;
60
+ #endif
50
61
51
62
private readonly ConcurrentDictionary < ( Type , int ) , bool > creating = new ConcurrentDictionary < ( Type , int ) , bool > ( ) ;
52
63
@@ -85,17 +96,18 @@ protected virtual object CreateInstance(ServiceRegistration serviceInfo)
85
96
return null ;
86
97
}
87
98
var pInfos = cachedInfo . Second ;
88
- if ( pInfos . Length == 0 ) {
99
+ var nArg = pInfos . Length ;
100
+ if ( nArg == 0 ) {
89
101
return Activator . CreateInstance ( serviceInfo . MappedType ) ;
90
102
}
91
103
var managedThreadId = Environment . CurrentManagedThreadId ;
92
104
var key = ( serviceInfo . Type , managedThreadId ) ;
93
105
if ( ! creating . TryAdd ( key , true ) ) {
94
106
throw new ActivationException ( Strings . ExRecursiveConstructorParameterDependencyIsDetected ) ;
95
107
}
96
- var args = new object [ pInfos . Length ] ;
108
+ var args = new object [ nArg ] ;
97
109
try {
98
- for ( var i = 0 ; i < pInfos . Length ; i ++ ) {
110
+ for ( var i = 0 ; i < nArg ; i ++ ) {
99
111
var type = pInfos [ i ] . ParameterType ;
100
112
if ( creating . ContainsKey ( ( type , managedThreadId ) ) ) {
101
113
throw new ActivationException ( Strings . ExRecursiveConstructorParameterDependencyIsDetected ) ;
@@ -106,10 +118,14 @@ protected virtual object CreateInstance(ServiceRegistration serviceInfo)
106
118
finally {
107
119
_ = creating . TryRemove ( key , out _ ) ;
108
120
}
121
+ #if NET8_0_OR_GREATER
122
+ return cInfo . Invoke ( args . AsSpan ( ) ) ;
123
+ #else
109
124
return cInfo . Invoke ( args ) ;
125
+ #endif
110
126
}
111
127
112
- #endregion
128
+ #endregion
113
129
114
130
#region Private \ internal methods
115
131
@@ -194,17 +210,28 @@ public static IServiceContainer Create(Type containerType, object configuration,
194
210
Type configurationType = configuration ? . GetType ( ) ,
195
211
parentType = parent ? . GetType ( ) ;
196
212
return ( IServiceContainer ) (
213
+ #if NET8_0_OR_GREATER
214
+ FindConstructorInvoker ( containerType , configurationType , parentType ) ? . Invoke ( configuration , parent )
215
+ ?? FindConstructorInvoker ( containerType , configurationType ) ? . Invoke ( configuration )
216
+ ?? FindConstructorInvoker ( containerType , parentType ) ? . Invoke ( parent )
217
+ #else
197
218
FindConstructor ( containerType , configurationType , parentType ) ? . Invoke ( new [ ] { configuration , parent } )
198
219
?? FindConstructor ( containerType , configurationType ) ? . Invoke ( new [ ] { configuration } )
199
220
?? FindConstructor ( containerType , parentType ) ? . Invoke ( new [ ] { parent } )
221
+ #endif
200
222
?? throw new ArgumentException ( Strings . ExContainerTypeDoesNotProvideASuitableConstructor , "containerType" )
201
223
) ;
202
224
}
203
225
226
+ #if NET8_0_OR_GREATER
227
+ private static ConstructorInvoker FindConstructorInvoker ( Type containerType , params Type [ ] argumentTypes ) =>
228
+ containerType . GetSingleConstructorInvokerOrDefault ( argumentTypes ) ;
229
+ #else
204
230
private static ConstructorInfo FindConstructor ( Type containerType , params Type [ ] argumentTypes ) =>
205
231
containerType . GetSingleConstructorOrDefault ( argumentTypes ) ;
232
+ #endif
206
233
207
- #endregion
234
+ #endregion
208
235
209
236
/// <summary>
210
237
/// Creates <see cref="IServiceContainer"/> by default configuration.
@@ -324,4 +351,4 @@ public override void Dispose()
324
351
}
325
352
}
326
353
}
327
- }
354
+ }
0 commit comments