Пример #1
0
        public void AddsAsAConvention()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            AutoFake.Provide <IDictionary <object, object?> >(properties);
            AutoFake.Provide <IServiceProvider>(properties);
            var configuration = new ConfigurationBuilder().Build();

            AutoFake.Provide <IConfiguration>(configuration);
            var finder = AutoFake.Resolve <IAssemblyCandidateFinder>();

            A.CallTo(() => finder.GetCandidateAssemblies(A <IEnumerable <string> > ._))
            .Returns(
                new[] { typeof(LoggingServiceConvention).Assembly, typeof(SerilogHostBuilderExtensions).Assembly }
                );

            properties[typeof(ILogger)] = Logger;
            var scanner = AutoFake.Resolve <SimpleConventionScanner>();

            AutoFake.Provide <IConventionScanner>(scanner);
            var services = new ServiceCollection();

            AutoFake.Provide <IServiceCollection>(services);

            var builder = AutoFake.Resolve <HostBuilder>();
            var sb      = AutoFake.Resolve <ServicesBuilder>();

            sb.Services.AddLogging(x => x.AddConsole().AddDebug());

            var sp = sb.Build();

            sp.GetService <ILoggerFactory>().Should().NotBeNull().And.BeOfType <SerilogLoggerFactory>();
        }
Пример #2
0
        public void AddsAsAConvention()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            AutoFake.Provide <IDictionary <object, object?> >(properties);
            AutoFake.Provide <IServiceProvider>(properties);
            var configuration = new ConfigurationBuilder().Build();

            AutoFake.Provide <IConfiguration>(configuration);
            var finder = AutoFake.Resolve <IAssemblyCandidateFinder>();

            A.CallTo(() => finder.GetCandidateAssemblies(A <IEnumerable <string> > ._))
            .Returns(new[] { typeof(LoggingHostBuilder2Extensions).Assembly });

            properties[typeof(ILogger)] = Logger;
            var scanner = AutoFake.Resolve <SimpleConventionScanner>();

            AutoFake.Provide <IConventionScanner>(scanner);
            var services = new ServiceCollection();

            AutoFake.Provide <IServiceCollection>(services);

            AutoFake.Resolve <HostBuilder>();
            var sb = AutoFake.Resolve <ServicesBuilder>();

            sb.Services.AddOptions();

            var sp = sb.Build();

            services.Should().Contain(x => x.ServiceType == typeof(IConfigureOptions <LoggerFilterOptions>));
            sp.GetRequiredService <IOptions <LoggerFilterOptions> >().Value.MinLevel.Should().Be(LogLevel.Information);
        }
Пример #3
0
        /// <summary>
        /// Gets the or create builder.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="startupInstance">The startup instance.</param>
        /// <param name="environment">The environment.</param>
        /// <returns>RocketFunctionHostBuilder.</returns>
        internal static RocketFunctionHostBuilder GetOrCreateBuilder(IWebJobsBuilder builder, object startupInstance, IRocketEnvironment environment)
        {
            if (!Builders.TryGetValue(builder, out var conventionalBuilder))
            {
                var diagnosticSource  = new DiagnosticListener("Rocket.Surgery.Hosting");
                var functionsAssembly = startupInstance.GetType().Assembly;

                var location = Path.GetDirectoryName(functionsAssembly.Location);
                DependencyContext dependencyContext = null;
                while (dependencyContext == null && !string.IsNullOrEmpty(location))
                {
                    var depsFilePath = Path.Combine(location, functionsAssembly.GetName().Name + ".deps.json");
                    if (File.Exists(depsFilePath))
                    {
                        using (var stream = File.Open(depsFilePath, FileMode.Open, FileAccess.Read))
                        {
                            dependencyContext = new DependencyContextJsonReader().Read(stream);
                            break;
                        }
                    }
                    location = Path.GetDirectoryName(location);
                }
                var logger = new DiagnosticLogger(diagnosticSource);
                var assemblyCandidateFinder = new DependencyContextAssemblyCandidateFinder(dependencyContext, logger);
                var assemblyProvider        = new DependencyContextAssemblyProvider(dependencyContext, logger);
                var properties = new ServiceProviderDictionary();
                var scanner    = new SimpleConventionScanner(assemblyCandidateFinder, properties, logger);
                conventionalBuilder = new RocketFunctionHostBuilder(builder, functionsAssembly, startupInstance, environment, scanner, assemblyCandidateFinder, assemblyProvider, diagnosticSource, properties);
                Builders.Add(builder, conventionalBuilder);
            }

            return(conventionalBuilder);
        }
Пример #4
0
        public void ShouldExcludeScannedItemsIfAddedManually()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProvider>(properties);
            var scanner = AutoFake.Resolve <Scanner>();
            var finder  = AutoFake.Resolve <IAssemblyCandidateFinder>();

            var myConvention1 = new Class1();
            var myConvention2 = new Class2();
            var myConvention3 = new Class3();

            A.CallTo(() => finder.GetCandidateAssemblies(A <IEnumerable <string> > ._))
            .Returns(
                new[]
            {
                typeof(ConventionScannerTests).GetTypeInfo().Assembly, typeof(Class1).GetTypeInfo().Assembly,
                typeof(Class2).GetTypeInfo().Assembly, typeof(Class3).GetTypeInfo().Assembly
            }
                );

            scanner.AppendConvention(myConvention1, myConvention3, myConvention2);
            scanner.ExceptConvention(typeof(ConventionScannerTests).Assembly);

            var provider = scanner.BuildProvider();

            var result = provider.GetAll()
                         .Select(x => x.Convention)
                         .ToArray();

            result.Should().ContainInOrder(myConvention1, myConvention3, myConvention2);
        }
        /// <summary>
        /// Gets the or create builder.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <returns>RocketHostBuilder.</returns>
        internal static RocketHostBuilder GetOrCreateBuilder(IHostBuilder builder)
        {
            if (!Builders.TryGetValue(builder, out var conventionalBuilder))
            {
                var diagnosticSource          = new DiagnosticListener("Rocket.Surgery.Hosting");
                var dependencyContext         = DependencyContext.Default;
                var logger                    = new DiagnosticLogger(diagnosticSource);
                var serviceProviderDictionary = new ServiceProviderDictionary(builder.Properties);
                serviceProviderDictionary.Set <ILogger>(logger);
                var assemblyCandidateFinder = new DependencyContextAssemblyCandidateFinder(dependencyContext, logger);
                var assemblyProvider        = new DependencyContextAssemblyProvider(dependencyContext, logger);
                var scanner = new SimpleConventionScanner(assemblyCandidateFinder, serviceProviderDictionary, logger);
                conventionalBuilder = new RocketHostBuilder(builder, scanner, assemblyCandidateFinder, assemblyProvider, diagnosticSource, serviceProviderDictionary);

                var host = new RocketContext(builder);
                builder
                .ConfigureHostConfiguration(host.CaptureArguments)
                .ConfigureHostConfiguration(host.ConfigureCli)
                .ConfigureAppConfiguration(host.ReplaceArguments)
                .ConfigureAppConfiguration(host.ConfigureAppConfiguration)
                .ConfigureServices(host.ConfigureServices)
                .ConfigureServices(host.DefaultServices);
                Builders.Add(builder, conventionalBuilder);
            }

            return(conventionalBuilder);
        }
        public void Should_Not_GetHostType()
        {
            var context    = A.Fake <IConventionHostBuilder>();
            var properties = new ServiceProviderDictionary();

            A.CallTo(() => context.ServiceProperties).Returns(properties);

            context.GetHostType().Should().Be(HostType.Undefined);
        }
Пример #7
0
        public void Should_Not_IsUnitTestHost()
        {
            var context    = A.Fake <IConventionContext>();
            var properties = new ServiceProviderDictionary();

            A.CallTo(() => context.Properties).Returns(properties);
            properties.Set(HostType.Live);

            context.IsUnitTestHost().Should().BeFalse();
        }
Пример #8
0
        public void Should_Get_HostType(HostType hostType)
        {
            var context    = A.Fake <IConventionContext>();
            var properties = new ServiceProviderDictionary();

            A.CallTo(() => context.Properties).Returns(properties);
            properties.Set(hostType);

            context.GetHostType().Should().Be(hostType);
        }
        public void Should_Get_TestHost()
        {
            var context    = A.Fake <IConventionHostBuilder>();
            var properties = new ServiceProviderDictionary();

            A.CallTo(() => context.ServiceProperties).Returns(properties);
            properties.Set(HostType.UnitTestHost);

            context.IsUnitTestHost().Should().BeTrue();
        }
Пример #10
0
        internal static RocketWasmHostBuilder GetOrCreateBuilder(IWebAssemblyHostBuilder builder, Assembly assembly = null)
        {
            if (!Builders.TryGetValue(builder, out var conventionalBuilder))
            {
                var diagnosticSource          = new DiagnosticListener("Rocket.Surgery.Blazor");
                var logger                    = new DiagnosticLogger(diagnosticSource);
                var serviceProviderDictionary = new ServiceProviderDictionary(builder.Properties);

                serviceProviderDictionary.Set <ILogger>(logger);
                serviceProviderDictionary.Set(HostType.Live);
                var assemblyCandidateFinder = new AppDomainAssemblyCandidateFinder(AppDomain.CurrentDomain, logger);
                var assemblyProvider        = new DefaultAssemblyProvider(AppDomain.CurrentDomain.GetAssemblies().Concat(GetAllAssemblies(assembly !)).ToArray());
Пример #11
0
        public void ShouldAppendConventions_AsAnArrayOfTypes()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder = AutoFake.Resolve <CCBuilder>();

            builder.AppendConvention(typeof(C), typeof(E), typeof(D));

            A.CallTo(() => builder.Scanner.AppendConvention(A <Type[]> .Ignored)).MustHaveHappened(1, Times.Exactly);
        }
Пример #12
0
        public void ShouldPrependConventions_AsAType()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder = AutoFake.Resolve <CCBuilder>();


            builder.PrependConvention <C>();

            A.CallTo(() => builder.Scanner.PrependConvention <C>()).MustHaveHappened(1, Times.Exactly);
        }
Пример #13
0
        public void ShouldResolveConventionsUsingTheServiceProvider_And_Fail_IfTypeIsNotProvided()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProvider>(properties);
            var scanner = AutoFake.Resolve <Scanner>();

            properties.Add(typeof(IConventionScanner), scanner);

            scanner.AppendConvention <F>();

            Action a = () => scanner.BuildProvider().Get <IServiceConvention, ServiceConventionDelegate>();

            a.Should().Throw <InvalidOperationException>();
        }
Пример #14
0
        public void ShouldConstruct()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            var builder = AutoFake.Resolve <CCBuilder>();

            builder.Should().NotBeNull();
            builder.Properties.Should().NotBeNull();
            builder.Scanner.Should().NotBeNull();

            builder["a"] = "b";

            builder["a"].Should().Be("b");
        }
Пример #15
0
        public void ShouldAppendConventions_AsASingle()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder    = AutoFake.Resolve <CCBuilder>();
            var convention = A.Fake <IServiceConvention>();

            builder.AppendConvention(convention);

            A.CallTo(() => builder.Scanner.AppendConvention(A <IConvention[]> .Ignored))
            .MustHaveHappened(1, Times.Exactly);
        }
        public void MustRegisterListeners_Implicitly()
        {
            AutoFake.Provide <IServiceCollection>(new ServiceCollection());
            var serviceProviderDictionary = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(serviceProviderDictionary);
            AutoFake.Provide <IServiceProvider>(serviceProviderDictionary);
            AutoFake.Provide <IDictionary <object, object?> >(serviceProviderDictionary);
            var scanner = AutoFake.Resolve <SimpleConventionScanner>();

            AutoFake.Provide <IConventionScanner>(scanner);
            serviceProviderDictionary.Set(
                new MartenOptions
            {
                SessionTracking = DocumentTracking.DirtyTracking,
                UseSession      = true
            }
                );
            var servicesBuilder = AutoFake.Resolve <ServicesBuilder>();

            servicesBuilder.Scanner.AppendConvention <MartenConvention>();
            servicesBuilder.Services.AddSingleton(A.Fake <IDocumentSessionListener>());
            servicesBuilder.Services.AddTransient <MartenRegistry, MyMartenRegistry>();
            servicesBuilder.Services.AddSingleton(LoggerFactory);
            servicesBuilder.Services.AddSingleton <IClock>(
                new FakeClock(
                    Instant.FromDateTimeOffset(DateTimeOffset.Now),
                    Duration.FromSeconds(1)
                    )
                );
            servicesBuilder.Services.AddScoped <IMartenContext>(
                _ => new MartenContext {
                User = new MartenUser <string>(() => "abc123")
            }
                );

            var serviceProvider = servicesBuilder.Build();
            var options         = serviceProvider.GetRequiredService <IOptions <StoreOptions> >().Value;

            options.Connection(() => new NpgsqlConnection());

            var session = serviceProvider.GetService <IDocumentSession>();

            session.Listeners.Count.Should().Be(1);
        }
Пример #17
0
        public void ShouldAppendConventions_AsAnEnumerable()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder     = AutoFake.Resolve <CCBuilder>();
            var convention  = A.Fake <IServiceConvention>(x => x.Named("convention"));
            var convention2 = A.Fake <IServiceConvention>(x => x.Named("convention2"));
            var convention3 = A.Fake <IServiceConvention>(x => x.Named("convention3"));

            var conventions = new[] { convention3, convention, convention2 }.AsEnumerable();

            builder.AppendConvention(conventions);

            A.CallTo(() => builder.Scanner.AppendConvention(A <IEnumerable <IConvention> > .Ignored))
            .MustHaveHappened(1, Times.Exactly);
        }
Пример #18
0
        public void ShouldPrependDelegates_AsAnArray()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder = AutoFake.Resolve <CCBuilder>();

            var convention  = A.Fake <ServiceConventionDelegate>(x => x.Named("convention"));
            var convention2 = A.Fake <ServiceConventionDelegate>(x => x.Named("convention2"));
            var convention3 = A.Fake <ServiceConventionDelegate>(x => x.Named("convention3"));

            var conventions = new[] { convention3, convention, convention2 };

            builder.PrependDelegate(conventions);

            A.CallTo(() => builder.Scanner.PrependDelegate(A <Delegate[]> .Ignored)).MustHaveHappened(1, Times.Exactly);
        }
Пример #19
0
        public void ShouldConstruct()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            using var diaglosticSource = new DiagnosticListener("DiagnosticSource");
            AutoFake.Provide <DiagnosticSource>(diaglosticSource);
            var builder = AutoFake.Resolve <CCBuilder>();

            builder.Should().NotBeNull();
            builder.Properties.Should().NotBeNull();
            builder.Should().NotBeNull();
            builder.AssemblyCandidateFinder.Should().NotBeNull();
            builder.AssemblyProvider.Should().NotBeNull();

            builder["a"] = "b";

            builder["a"].Should().Be("b");
        }
Пример #20
0
        public void ShouldPrependDelegates()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            var builder = AutoFake.Resolve <CCBuilder>();

            var conventionsArray      = Enumerable.Range(0, 10).Select(x => A.Fake <ServiceConventionDelegate>()).ToArray();
            var conventionsEnumerable = Enumerable.Range(0, 10).Select(x => A.Fake <ServiceConventionDelegate>());

            builder.PrependDelegate(conventionsArray)
            .PrependDelegate(conventionsEnumerable);

            A.CallTo(() => builder.Scanner.PrependDelegate(A <Delegate[]> .Ignored))
            .MustHaveHappened(1, Times.Exactly);

            A.CallTo(() => builder.Scanner.PrependDelegate(A <IEnumerable <Delegate> > .Ignored))
            .MustHaveHappened(1, Times.Exactly);
        }
Пример #21
0
        public void ShouldResolveConventionsUsingTheServiceProvider_IgnoringDefaultValues()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProvider>(properties);
            var scanner = AutoFake.Resolve <Scanner>();

            properties.Add(typeof(IConventionScanner), scanner);

            scanner.AppendConvention <F_WithDefault>();

            var result = scanner.BuildProvider().Get <IServiceConvention, ServiceConventionDelegate>();

            var item = result.First().Convention;

            item.Should().BeOfType <F_WithDefault>();
            ((F_WithDefault)item !).Scanner.Should().NotBeNull();
            ((F_WithDefault)item !).Scanner.Should().BeSameAs(scanner);
            ((F_WithDefault)item !).Service.Should().BeNull();
        }
Пример #22
0
        public void AddsLogging()
        {
            var properties = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(properties);
            AutoFake.Provide <IDictionary <object, object?> >(properties);
            AutoFake.Provide <IServiceProvider>(properties);
            var configuration = new ConfigurationBuilder().Build();

            AutoFake.Provide <IConfiguration>(configuration);

            properties[typeof(ILogger)] = Logger;
            var scanner = AutoFake.Resolve <SimpleConventionScanner>();

            AutoFake.Provide <IConventionScanner>(scanner);
            var services = new ServiceCollection();

            AutoFake.Provide <IServiceCollection>(services);

            var builder = AutoFake.Resolve <HostBuilder>();
            var sb      = AutoFake.Resolve <ServicesBuilder>();
        public void MustRegisterListeners_Explicitly()
        {
            AutoFake.Provide <IServiceCollection>(new ServiceCollection());
            var serviceProviderDictionary = new ServiceProviderDictionary();

            AutoFake.Provide <IServiceProviderDictionary>(serviceProviderDictionary);
            AutoFake.Provide <IServiceProvider>(serviceProviderDictionary);
            AutoFake.Provide <IDictionary <object, object?> >(serviceProviderDictionary);
            var servicesBuilder = AutoFake.Resolve <ServicesBuilder>();

            AutoFake.Provide(A.Fake <IDocumentSessionListener>());
            servicesBuilder.Services.AddSingleton(A.Fake <IDocumentSessionListener>());
            servicesBuilder.Services.AddTransient <MartenRegistry, MyMartenRegistry>();
            servicesBuilder.Services.AddSingleton(LoggerFactory);
            servicesBuilder.Services.AddSingleton <IClock>(
                new FakeClock(
                    Instant.FromDateTimeOffset(DateTimeOffset.Now),
                    Duration.FromSeconds(1)
                    )
                );
            var martenBuilder = servicesBuilder.WithMarten();

            servicesBuilder.Services.AddScoped <IMartenContext>(
                _ => new MartenContext {
                User = new MartenUser <string>(() => "abc123")
            }
                );

            var serviceProvider = servicesBuilder.Build();
            var options         = serviceProvider.GetRequiredService <IOptions <StoreOptions> >().Value;

            options.Connection(() => new NpgsqlConnection());

            using (var scope = serviceProvider.GetService <IServiceScopeFactory>().CreateScope())
            {
                var session = scope.ServiceProvider.GetService <IDocumentStore>().LightweightSession();
                session.Listeners.Count.Should().Be(1);
            }
        }
Пример #24
0
        /// <summary>
        /// Gets the or create builder.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="startupInstance">The startup instance.</param>
        /// <param name="environment">The environment.</param>
        /// <returns>RocketFunctionHostBuilder.</returns>
        internal static RocketFunctionHostBuilder GetOrCreateBuilder(
            IWebJobsBuilder builder,
            object startupInstance,
            IRocketEnvironment?environment
            )
        {
            if (!Builders.TryGetValue(builder, out var conventionalBuilder))
            {
                var diagnosticSource  = new DiagnosticListener("Rocket.Surgery.Hosting");
                var functionsAssembly = startupInstance.GetType().Assembly;

                var location = Path.GetDirectoryName(functionsAssembly.Location);
                DependencyContext?dependencyContext = null;
                while (!string.IsNullOrEmpty(location))
                {
                    var depsFilePath = Path.Combine(location, functionsAssembly.GetName().Name + ".deps.json");
                    if (File.Exists(depsFilePath))
                    {
                        using var stream  = File.Open(depsFilePath, FileMode.Open, FileAccess.Read);
                        using var reader  = new DependencyContextJsonReader();
                        dependencyContext = reader.Read(stream);
                        break;
                    }

                    location = Path.GetDirectoryName(location);
                }

                var logger = new DiagnosticLogger(diagnosticSource);
                var assemblyCandidateFinder = new DependencyContextAssemblyCandidateFinder(dependencyContext !, logger);
                var assemblyProvider        = new DependencyContextAssemblyProvider(dependencyContext !, logger);
                var properties = new ServiceProviderDictionary();
                properties.Set <ILogger>(logger);
                properties.Set(HostType.Live);
                var scanner = new SimpleConventionScanner(assemblyCandidateFinder, properties, logger);
                conventionalBuilder = new RocketFunctionHostBuilder(
                    builder,
                    functionsAssembly,
                    startupInstance,
                    environment !,
                    scanner,
                    assemblyCandidateFinder,
                    assemblyProvider,
                    diagnosticSource,
                    properties
                    );
                conventionalBuilder.Set(
                    new ConfigurationOptions
                {
                    ApplicationConfiguration =
                    {
                        b => b.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true),
                        b => b.AddYamlFile("appsettings.yml",  optional: true, reloadOnChange: true),
                        b => b.AddYamlFile("appsettings.yaml", optional: true, reloadOnChange: true),
                        b => b.AddIniFile("appsettings.ini",   optional: true, reloadOnChange: true)
                    },
                    EnvironmentConfiguration =
                    {
                        (b, environmentName) => b.AddJsonFile(
                            $"appsettings.{environmentName}.json",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddYamlFile(
                            $"appsettings.{environmentName}.yml",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddYamlFile(
                            $"appsettings.{environmentName}.yaml",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddIniFile(
                            $"appsettings.{environmentName}.ini",
                            optional: true,
                            reloadOnChange: true
                            )
                    }
                }
                    );
                Builders.Add(builder, conventionalBuilder);
            }

            return(conventionalBuilder);
        }
Пример #25
0
        /// <summary>
        /// Gets the or create builder.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <returns>RocketHostBuilder.</returns>
        internal static RocketHostBuilder GetOrCreateBuilder(IHostBuilder builder)
        {
            if (!Builders.TryGetValue(builder, out var conventionalBuilder))
            {
                var diagnosticSource          = new DiagnosticListener("Rocket.Surgery.Hosting");
                var dependencyContext         = DependencyContext.Default;
                var logger                    = new DiagnosticLogger(diagnosticSource);
                var serviceProviderDictionary = new ServiceProviderDictionary(builder.Properties);
                serviceProviderDictionary.Set <ILogger>(logger);
                serviceProviderDictionary.Set(HostType.Live);
                var assemblyCandidateFinder = new DependencyContextAssemblyCandidateFinder(dependencyContext, logger);
                var assemblyProvider        = new DependencyContextAssemblyProvider(dependencyContext, logger);
                var scanner = new SimpleConventionScanner(assemblyCandidateFinder, serviceProviderDictionary, logger);
                conventionalBuilder = new RocketHostBuilder(
                    builder,
                    scanner,
                    assemblyCandidateFinder,
                    assemblyProvider,
                    diagnosticSource,
                    serviceProviderDictionary
                    );

                conventionalBuilder.Set(
                    new ConfigurationOptions
                {
                    ApplicationConfiguration =
                    {
                        b => b.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true),
                        b => b.AddYamlFile("appsettings.yml",  optional: true, reloadOnChange: true),
                        b => b.AddYamlFile("appsettings.yaml", optional: true, reloadOnChange: true),
                        b => b.AddIniFile("appsettings.ini",   optional: true, reloadOnChange: true)
                    },
                    EnvironmentConfiguration =
                    {
                        (b, environmentName) => b.AddJsonFile(
                            $"appsettings.{environmentName}.json",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddYamlFile(
                            $"appsettings.{environmentName}.yml",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddYamlFile(
                            $"appsettings.{environmentName}.yaml",
                            optional: true,
                            reloadOnChange: true
                            ),
                        (b, environmentName) => b.AddIniFile(
                            $"appsettings.{environmentName}.ini",
                            optional: true,
                            reloadOnChange: true
                            )
                    }
                }
                    );

                var host = new RocketContext(builder);
                builder
                .ConfigureHostConfiguration(host.ComposeHostingConvention)
                .ConfigureHostConfiguration(host.CaptureArguments)
                .ConfigureHostConfiguration(host.ConfigureCli)
                .ConfigureAppConfiguration(host.ReplaceArguments)
                .ConfigureAppConfiguration(host.ConfigureAppConfiguration)
                .ConfigureServices(host.ConfigureServices)
                .ConfigureServices(host.DefaultServices);
                Builders.Add(builder, conventionalBuilder);
            }

            return(conventionalBuilder);
        }