@@ -94,6 +94,8 @@ protected override Expression VisitSingleton(SingletonCallSite singletonCallSite
9494 return null ;
9595 }
9696
97+ // this.RuntimeResolver.Resolve(singletonCallSite)
98+
9799 argument . Generator . Emit ( OpCodes . Ldarg_0 ) ;
98100 argument . Generator . Emit ( OpCodes . Ldfld , RuntimeResolverField ) ;
99101
@@ -108,6 +110,18 @@ protected override Expression VisitSingleton(SingletonCallSite singletonCallSite
108110
109111 protected override Expression VisitScoped ( ScopedCallSite scopedCallSite , ILEmitResolverBuilderContext argument )
110112 {
113+
114+ // var cacheKey = scopedCallSite.CacheKey;
115+ // if (ProviderScope.ResolvedServices.TryGetValue(cacheKey, out value)
116+ // {
117+ // [return] value
118+ // }
119+ // else
120+ // {
121+ // value = [createvalue];
122+ // ProviderScope.ResolvedServices.Add(cacheKey, value);
123+ // }
124+
111125 var resultLocal = argument . Generator . DeclareLocal ( scopedCallSite . ServiceType ) ;
112126 var cacheKeyLocal = argument . Generator . DeclareLocal ( typeof ( object ) ) ;
113127 var endLabel = argument . Generator . DefineLabel ( ) ;
@@ -119,7 +133,7 @@ protected override Expression VisitScoped(ScopedCallSite scopedCallSite, ILEmitR
119133 // Duplicate cache key
120134 argument . Generator . Emit ( OpCodes . Dup ) ;
121135 // and store to local
122- StLoc ( argument . Generator , cacheKeyLocal . LocalIndex ) ;
136+ Stloc ( argument . Generator , cacheKeyLocal . LocalIndex ) ;
123137
124138 // Load address of local
125139 argument . Generator . Emit ( OpCodes . Ldloca , resultLocal . LocalIndex ) ;
@@ -143,15 +157,15 @@ protected override Expression VisitScoped(ScopedCallSite scopedCallSite, ILEmitR
143157
144158 argument . Generator . Emit ( OpCodes . Ldloc_0 ) ;
145159 // Load cache key
146- LdLoc ( argument . Generator , cacheKeyLocal . LocalIndex ) ;
160+ Ldloc ( argument . Generator , cacheKeyLocal . LocalIndex ) ;
147161 // Load value
148- LdLoc ( argument . Generator , resultLocal . LocalIndex ) ;
162+ Ldloc ( argument . Generator , resultLocal . LocalIndex ) ;
149163
150164 argument . Generator . Emit ( OpCodes . Callvirt , ExpressionResolverBuilder . AddMethodInfo ) ;
151165
152166 // Load result and return it
153167 argument . Generator . MarkLabel ( endLabel ) ;
154- LdLoc ( argument . Generator , resultLocal . LocalIndex ) ;
168+ Ldloc ( argument . Generator , resultLocal . LocalIndex ) ;
155169
156170 return null ;
157171 }
@@ -164,46 +178,51 @@ protected override Expression VisitConstant(ConstantCallSite constantCallSite, I
164178
165179 protected override Expression VisitCreateInstance ( CreateInstanceCallSite createInstanceCallSite , ILEmitResolverBuilderContext argument )
166180 {
181+ // new Type
167182 argument . Generator . Emit ( OpCodes . Newobj , createInstanceCallSite . ImplementationType . GetConstructor ( Type . EmptyTypes ) ) ;
168183 return null ;
169184 }
170185
171186 protected override Expression VisitServiceProvider ( ServiceProviderCallSite serviceProviderCallSite , ILEmitResolverBuilderContext argument )
172187 {
173- // provider
188+ // [return] ProviderScope
174189 argument . Generator . Emit ( OpCodes . Ldarg_1 ) ;
175190 return null ;
176191 }
177192
178193 protected override Expression VisitServiceScopeFactory ( ServiceScopeFactoryCallSite serviceScopeFactoryCallSite , ILEmitResolverBuilderContext argument )
179194 {
180- // this
195+ // this.ScopeFactory
181196 argument . Generator . Emit ( OpCodes . Ldarg_0 ) ;
182- // .ScopeFactory
183197 argument . Generator . Emit ( OpCodes . Ldfld , typeof ( ILEmitResolverBuilderRuntimeContext ) . GetField ( nameof ( ILEmitResolverBuilderRuntimeContext . ScopeFactory ) ) ) ;
184198 return null ;
185199 }
186200
187201 protected override Expression VisitIEnumerable ( IEnumerableCallSite enumerableCallSite , ILEmitResolverBuilderContext argument )
188202 {
203+
189204 if ( enumerableCallSite . ServiceCallSites . Length == 0 )
190205 {
191206 argument . Generator . Emit ( OpCodes . Call , ExpressionResolverBuilder . ArrayEmptyMethodInfo . MakeGenericMethod ( enumerableCallSite . ItemType ) ) ;
192207 }
193208 else
194209 {
195- // push length
210+
211+ // var array = new ItemType[];
212+ // array[0] = [Create argument0];
213+ // array[1] = [Create argument1];
214+ // ...
196215 argument . Generator . Emit ( OpCodes . Ldc_I4 , enumerableCallSite . ServiceCallSites . Length ) ;
197- // new ItemType[length]
198216 argument . Generator . Emit ( OpCodes . Newarr , enumerableCallSite . ItemType ) ;
199217 for ( int i = 0 ; i < enumerableCallSite . ServiceCallSites . Length ; i ++ )
200218 {
201- // array
219+ // duplicate array
202220 argument . Generator . Emit ( OpCodes . Dup ) ;
203221 // push index
204222 argument . Generator . Emit ( OpCodes . Ldc_I4 , i ) ;
205223 // create parameter
206224 VisitCallSite ( enumerableCallSite . ServiceCallSites [ i ] , argument ) ;
225+ // store
207226 argument . Generator . Emit ( OpCodes . Stelem , enumerableCallSite . ItemType ) ;
208227 }
209228 }
@@ -218,19 +237,14 @@ protected override Expression VisitFactory(FactoryCallSite factoryCallSite, ILEm
218237 argument . Factories = new List < Func < IServiceProvider , object > > ( ) ;
219238 }
220239
221- // this
240+ // this.Factories[i](ProviderScope)
222241 argument . Generator . Emit ( OpCodes . Ldarg_0 ) ;
223- // .Factories
224242 argument . Generator . Emit ( OpCodes . Ldfld , FactoriesField ) ;
225243
226- // i
227244 argument . Generator . Emit ( OpCodes . Ldc_I4 , argument . Factories . Count ) ;
228- // [ ]
229245 argument . Generator . Emit ( OpCodes . Ldelem , typeof ( Func < IServiceProvider , object > ) ) ;
230246
231- // provider
232247 argument . Generator . Emit ( OpCodes . Ldarg_1 ) ;
233- // ( )
234248 argument . Generator . Emit ( OpCodes . Call , ExpressionResolverBuilder . InvokeFactoryMethodInfo ) ;
235249
236250 argument . Factories . Add ( factoryCallSite . Factory ) ;
@@ -244,7 +258,8 @@ private void AddConstant(ILEmitResolverBuilderContext argument, object value)
244258 {
245259 argument . Constants = new List < object > ( ) ;
246260 }
247-
261+
262+ // this.Constants[i]
248263 argument . Generator . Emit ( OpCodes . Ldarg_0 ) ;
249264 argument . Generator . Emit ( OpCodes . Ldfld , ConstantsField ) ;
250265
@@ -256,10 +271,17 @@ private void AddConstant(ILEmitResolverBuilderContext argument, object value)
256271
257272 private Func < ServiceProviderEngineScope , object > BuildType ( IServiceCallSite callSite )
258273 {
259- var dynamicMethod = new DynamicMethod ( "ResolveService" , MethodAttributes . Public | MethodAttributes . Static , CallingConventions . Standard , typeof ( object ) , new [ ] { typeof ( ILEmitResolverBuilderRuntimeContext ) , typeof ( ServiceProviderEngineScope ) } , GetType ( ) , true ) ;
274+ // We need to skit visibility checks because services/constructors might be private
275+ var dynamicMethod = new DynamicMethod ( "ResolveService" ,
276+ attributes : MethodAttributes . Public | MethodAttributes . Static ,
277+ callingConvention : CallingConventions . Standard ,
278+ returnType : typeof ( object ) ,
279+ parameterTypes : new [ ] { typeof ( ILEmitResolverBuilderRuntimeContext ) , typeof ( ServiceProviderEngineScope ) } ,
280+ owner : GetType ( ) ,
281+ skipVisibility : true ) ;
260282
261283 var info = ILEmitCallSiteAnalyzer . Instance . CollectGenerationInfo ( callSite ) ;
262- var context2 = GenerateMethodBody ( callSite , dynamicMethod . GetILGenerator ( info . Size ) , info ) ;
284+ var runtimeContext = GenerateMethodBody ( callSite , dynamicMethod . GetILGenerator ( info . Size ) , info ) ;
263285
264286#if SAVE_ASSEMBLY
265287 var assemblyName = "Test" + DateTime . Now . Ticks ;
@@ -278,7 +300,7 @@ private Func<ServiceProviderEngineScope, object> BuildType(IServiceCallSite call
278300 assembly . Save ( assemblyName + ".dll" ) ;
279301#endif
280302
281- return ( Func < ServiceProviderEngineScope , object > ) dynamicMethod . CreateDelegate ( typeof ( Func < ServiceProviderEngineScope , object > ) , context2 ) ;
303+ return ( Func < ServiceProviderEngineScope , object > ) dynamicMethod . CreateDelegate ( typeof ( Func < ServiceProviderEngineScope , object > ) , runtimeContext ) ;
282304 }
283305
284306 private ILEmitResolverBuilderRuntimeContext GenerateMethodBody ( IServiceCallSite callSite , ILGenerator generator , ILEmitCallSiteAnalysisResult info )
@@ -320,7 +342,7 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(IServiceCallSite
320342 {
321343 var resultLocal = context . Generator . DeclareLocal ( typeof ( object ) ) ;
322344
323- StLoc ( context . Generator , resultLocal . LocalIndex ) ;
345+ Stloc ( context . Generator , resultLocal . LocalIndex ) ;
324346 context . Generator . BeginFinallyBlock ( ) ;
325347
326348 var postExitLabel = context . Generator . DefineLabel ( ) ;
@@ -335,7 +357,7 @@ private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(IServiceCallSite
335357
336358 context . Generator . EndExceptionBlock ( ) ;
337359
338- LdLoc ( context . Generator , resultLocal . LocalIndex ) ;
360+ Ldloc ( context . Generator , resultLocal . LocalIndex ) ;
339361 }
340362
341363 context . Generator . Emit ( OpCodes . Ret ) ;
@@ -359,7 +381,7 @@ private bool TryResolveSingletonValue(SingletonCallSite singletonCallSite, out o
359381
360382 private static bool BeginCaptureDisposable ( Type implType , ILEmitResolverBuilderContext argument )
361383 {
362- var shouldCapture = ! ( implType != null && ! typeof ( IDisposable ) . GetTypeInfo ( ) . IsAssignableFrom ( implType . GetTypeInfo ( ) ) ) ;
384+ var shouldCapture = implType == null || typeof ( IDisposable ) . GetTypeInfo ( ) . IsAssignableFrom ( implType . GetTypeInfo ( ) ) ;
363385
364386 if ( shouldCapture )
365387 {
@@ -369,12 +391,13 @@ private static bool BeginCaptureDisposable(Type implType, ILEmitResolverBuilderC
369391
370392 return shouldCapture ;
371393 }
394+
372395 private static void EndCaptureDisposable ( ILEmitResolverBuilderContext argument )
373396 {
374397 argument . Generator . Emit ( OpCodes . Callvirt , ExpressionResolverBuilder . CaptureDisposableMethodInfo ) ;
375398 }
376399
377- private void LdLoc ( ILGenerator generator , int index )
400+ private void Ldloc ( ILGenerator generator , int index )
378401 {
379402 switch ( index )
380403 {
@@ -397,7 +420,7 @@ private void LdLoc(ILGenerator generator, int index)
397420 generator . Emit ( OpCodes . Ldloc , index ) ;
398421 }
399422
400- private void StLoc ( ILGenerator generator , int index )
423+ private void Stloc ( ILGenerator generator , int index )
401424 {
402425 switch ( index )
403426 {
0 commit comments