@@ -29,24 +29,35 @@ public class ServiceContainer : ServiceContainerBase
2929 {
3030 private static readonly Type iServiceContainerType = typeof ( IServiceContainer ) ;
3131
32+ #if NET8_0_OR_GREATER
33+ private static readonly Func < ServiceRegistration , Pair < ConstructorInvoker , ParameterInfo [ ] > > ConstructorFactory = serviceInfo => {
34+ #else
3235 private static readonly Func < ServiceRegistration , Pair < ConstructorInfo , ParameterInfo [ ] > > ConstructorFactory = serviceInfo => {
36+ #endif
3337 var mappedType = serviceInfo . MappedType ;
3438 var ctor = (
3539 from c in mappedType . GetConstructors ( )
3640 where c . GetAttribute < ServiceConstructorAttribute > ( AttributeSearchOptions . InheritNone ) != null
3741 select c
3842 ) . SingleOrDefault ( ) ?? mappedType . GetConstructor ( Array . Empty < Type > ( ) ) ;
3943 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
4149 } ;
4250
4351 private readonly IReadOnlyDictionary < Key , List < ServiceRegistration > > types ;
4452
4553 private readonly ConcurrentDictionary < ServiceRegistration , Lazy < object > > instances =
4654 new ConcurrentDictionary < ServiceRegistration , Lazy < object > > ( ) ;
4755
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
5061
5162 private readonly ConcurrentDictionary < ( Type , int ) , bool > creating = new ConcurrentDictionary < ( Type , int ) , bool > ( ) ;
5263
@@ -85,17 +96,18 @@ protected virtual object CreateInstance(ServiceRegistration serviceInfo)
8596 return null ;
8697 }
8798 var pInfos = cachedInfo . Second ;
88- if ( pInfos . Length == 0 ) {
99+ var nArg = pInfos . Length ;
100+ if ( nArg == 0 ) {
89101 return Activator . CreateInstance ( serviceInfo . MappedType ) ;
90102 }
91103 var managedThreadId = Environment . CurrentManagedThreadId ;
92104 var key = ( serviceInfo . Type , managedThreadId ) ;
93105 if ( ! creating . TryAdd ( key , true ) ) {
94106 throw new ActivationException ( Strings . ExRecursiveConstructorParameterDependencyIsDetected ) ;
95107 }
96- var args = new object [ pInfos . Length ] ;
108+ var args = new object [ nArg ] ;
97109 try {
98- for ( var i = 0 ; i < pInfos . Length ; i ++ ) {
110+ for ( var i = 0 ; i < nArg ; i ++ ) {
99111 var type = pInfos [ i ] . ParameterType ;
100112 if ( creating . ContainsKey ( ( type , managedThreadId ) ) ) {
101113 throw new ActivationException ( Strings . ExRecursiveConstructorParameterDependencyIsDetected ) ;
@@ -106,10 +118,14 @@ protected virtual object CreateInstance(ServiceRegistration serviceInfo)
106118 finally {
107119 _ = creating . TryRemove ( key , out _ ) ;
108120 }
121+ #if NET8_0_OR_GREATER
122+ return cInfo . Invoke ( args . AsSpan ( ) ) ;
123+ #else
109124 return cInfo . Invoke ( args ) ;
125+ #endif
110126 }
111127
112- #endregion
128+ #endregion
113129
114130 #region Private \ internal methods
115131
@@ -194,17 +210,28 @@ public static IServiceContainer Create(Type containerType, object configuration,
194210 Type configurationType = configuration ? . GetType ( ) ,
195211 parentType = parent ? . GetType ( ) ;
196212 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
197218 FindConstructor ( containerType , configurationType , parentType ) ? . Invoke ( new [ ] { configuration , parent } )
198219 ?? FindConstructor ( containerType , configurationType ) ? . Invoke ( new [ ] { configuration } )
199220 ?? FindConstructor ( containerType , parentType ) ? . Invoke ( new [ ] { parent } )
221+ #endif
200222 ?? throw new ArgumentException ( Strings . ExContainerTypeDoesNotProvideASuitableConstructor , "containerType" )
201223 ) ;
202224 }
203225
226+ #if NET8_0_OR_GREATER
227+ private static ConstructorInvoker FindConstructorInvoker ( Type containerType , params Type [ ] argumentTypes ) =>
228+ containerType . GetSingleConstructorInvokerOrDefault ( argumentTypes ) ;
229+ #else
204230 private static ConstructorInfo FindConstructor ( Type containerType , params Type [ ] argumentTypes ) =>
205231 containerType . GetSingleConstructorOrDefault ( argumentTypes ) ;
232+ #endif
206233
207- #endregion
234+ #endregion
208235
209236 /// <summary>
210237 /// Creates <see cref="IServiceContainer"/> by default configuration.
@@ -324,4 +351,4 @@ public override void Dispose()
324351 }
325352 }
326353 }
327- }
354+ }
0 commit comments