private GeneratedMethod BuildTypeNoCache(ServiceCallSite callSite) { // We need to skip visibility checks because services/constructors might be private var dynamicMethod = new DynamicMethod("ResolveService", attributes: MethodAttributes.Public | MethodAttributes.Static, callingConvention: CallingConventions.Standard, returnType: typeof(object), parameterTypes: new[] { typeof(ILEmitResolverBuilderRuntimeContext), typeof(ServiceProviderEngineScope) }, owner: GetType(), skipVisibility: true); // In traces we've seen methods range from 100B - 4K sized methods since we've // stop trying to inline everything into scoped methods. We'll pay for a couple of resizes // so there'll be allocations but we could potentially change ILGenerator to use the array pool ILGenerator ilGenerator = dynamicMethod.GetILGenerator(512); ILEmitResolverBuilderRuntimeContext runtimeContext = GenerateMethodBody(callSite, ilGenerator); #if SAVE_ASSEMBLIES var assemblyName = "Test" + DateTime.Now.Ticks; var fileName = assemblyName + ".dll"; var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.RunAndSave); var module = assembly.DefineDynamicModule(assemblyName, fileName); var type = module.DefineType(callSite.ServiceType.Name + "Resolver"); var method = type.DefineMethod( "ResolveService", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(object), new[] { typeof(ILEmitResolverBuilderRuntimeContext), typeof(ServiceProviderEngineScope) }); GenerateMethodBody(callSite, method.GetILGenerator()); type.CreateTypeInfo(); // Assembly.Save is only available in .NET Framework (https://github.com/dotnet/runtime/issues/15704) assembly.Save(fileName); #endif DependencyInjectionEventSource.Log.DynamicMethodBuilt(_rootScope.RootProvider, callSite.ServiceType, ilGenerator.ILOffset); return(new GeneratedMethod() { Lambda = (Func <ServiceProviderEngineScope, object>)dynamicMethod.CreateDelegate(typeof(Func <ServiceProviderEngineScope, object>), runtimeContext), Context = runtimeContext, DynamicMethod = dynamicMethod }); }
private GeneratedMethod BuildTypeNoCache(ServiceCallSite callSite) { // We need to skip visibility checks because services/constructors might be private var dynamicMethod = new DynamicMethod("ResolveService", attributes: MethodAttributes.Public | MethodAttributes.Static, callingConvention: CallingConventions.Standard, returnType: typeof(object), parameterTypes: new[] { typeof(ILEmitResolverBuilderRuntimeContext), typeof(ServiceProviderEngineScope) }, owner: GetType(), skipVisibility: true); ILEmitCallSiteAnalysisResult info = ILEmitCallSiteAnalyzer.Instance.CollectGenerationInfo(callSite); ILGenerator ilGenerator = dynamicMethod.GetILGenerator(info.Size); ILEmitResolverBuilderRuntimeContext runtimeContext = GenerateMethodBody(callSite, ilGenerator); #if SAVE_ASSEMBLIES var assemblyName = "Test" + DateTime.Now.Ticks; var fileName = "Test" + DateTime.Now.Ticks; var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.RunAndSave); var module = assembly.DefineDynamicModule(assemblyName, assemblyName + ".dll"); var type = module.DefineType("Resolver"); var method = type.DefineMethod( "ResolveService", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(object), new[] { typeof(ILEmitResolverBuilderRuntimeContext), typeof(ServiceProviderEngineScope) }); GenerateMethodBody(callSite, method.GetILGenerator(), info); type.CreateTypeInfo(); assembly.Save(assemblyName + ".dll"); #endif DependencyInjectionEventSource.Log.DynamicMethodBuilt(callSite.ServiceType, ilGenerator.ILOffset); return(new GeneratedMethod() { Lambda = (Func <ServiceProviderEngineScope, object>)dynamicMethod.CreateDelegate(typeof(Func <ServiceProviderEngineScope, object>), runtimeContext), Context = runtimeContext, DynamicMethod = dynamicMethod }); }