private IServiceProvider CreateServiceProviderCore(IEnumerable <ICodeGenerator> codeGenerators, ILogger logger, Action <ILogger, string, Exception> log4GenerateCode)
        {
            var generatedTypes    = new List <GeneratedTypeEntry>();
            var generationContext = new CodeGenerationContext();

            generationContext.WriteLines("using System;");
            generationContext.WriteLines("using System.Reflection;");
            generationContext.WriteLines("using System.Threading.Tasks;");
            generationContext.WriteLines("using Microsoft.Extensions.DependencyInjection;");
            generationContext.WriteLines("");

            generationContext.WriteLines("namespace Dora.Interception.CodeGeneration");
            using (generationContext.CodeBlock())
            {
                foreach (var service in _services)
                {
                    foreach (var generator in codeGenerators)
                    {
                        if (generator.TryGenerate(service, generationContext, out var proxyTypeNames))
                        {
                            generatedTypes.Add(new GeneratedTypeEntry(service, proxyTypeNames !, generator));
                            break;
                        }
                    }
                }
            }

            log4GenerateCode(logger, generationContext.SourceCode, null !);

            if (generatedTypes.Any())
            {
                var compilation = CSharpCompilation.Create("Dora.Interception.CodeGeneration")
                                  .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release))
                                  .AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(generationContext.SourceCode))
                                  .AddReferences(generationContext.References.Select(it => MetadataReference.CreateFromFile(it.Location)));

                Assembly outputAssembly;
                using var stream = new MemoryStream();
                var compilationResult = compilation.Emit(stream);

                if (!compilationResult.Success)
                {
                    var error = string.Join(Environment.NewLine, compilationResult.Diagnostics);
                    throw new InterceptionException($"It fails to generate proxy class. \n {error}");
                }

                var bytes = stream.ToArray();
                outputAssembly = Assembly.Load(bytes);

                foreach (var entry in generatedTypes)
                {
                    var proxyTypes = entry.ProxyTypeNames.Select(it => outputAssembly.GetType(it)).ToArray();
                    entry.CodeGenerator.RegisterProxyType(_services, entry.ServiceDescriptor, proxyTypes !);
                }
            }
            _services.Replace(ServiceDescriptor.Singleton <IServiceLifetimeProvider> (new ServiceLifetimeProvider(_services)));
            var serviceProvider = _services.BuildServiceProvider(_serviceProviderOptions);

            ((ApplicationServicesAccessor)serviceProvider.GetRequiredService <IApplicationServicesAccessor>()).ApplicationServices = serviceProvider;
            MethodInvokerBuilder.Instance = serviceProvider.GetRequiredService <IMethodInvokerBuilder>();
            return(serviceProvider);
        }