< Summary

Information
Class: NexusLabs.Needlr.Hosting.HostSyringe
Assembly: NexusLabs.Needlr.Hosting
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Hosting/HostSyringe.cs
Line coverage
94%
Covered lines: 32
Uncovered lines: 2
Coverable lines: 34
Total lines: 154
Line coverage: 94.1%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_BaseSyringe()100%11100%
get_OptionsFactory()100%11100%
get_HostFactoryCreator()100%11100%
get_ConfigureCallback()100%11100%
.ctor(...)100%11100%
BuildHost()50%2295.45%
BuildServiceProvider(...)100%210%
GetOrCreateHostFactory(...)75%44100%
GetOrCreateOptions()100%44100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Hosting/HostSyringe.cs

#LineLine coverage
 1using Microsoft.Extensions.Configuration;
 2using Microsoft.Extensions.Hosting;
 3
 4using NexusLabs.Needlr.Injection;
 5
 6namespace NexusLabs.Needlr.Hosting;
 7
 8/// <summary>
 9/// Provides a fluent API for configuring and building host applications using Needlr.
 10/// Wraps a ConfiguredSyringe with additional host functionality.
 11/// </summary>
 12/// <example>
 13/// Creating and configuring a HostSyringe:
 14/// <code>
 15/// // Transition from ConfiguredSyringe
 16/// var hostSyringe = new Syringe()
 17///     .UsingReflection()
 18///     .ForHost();
 19///
 20/// // Build and run the host
 21/// var host = hostSyringe
 22///     .UsingOptions(() => CreateHostOptions.Default.UsingArgs(args))
 23///     .UsingConfigurationCallback((builder, options) =>
 24///     {
 25///         // Configure the HostApplicationBuilder
 26///         builder.Configuration.AddJsonFile("custom-settings.json", optional: true);
 27///         builder.Services.AddSingleton&lt;IMyCustomService, MyCustomService&gt;();
 28///     })
 29///     .BuildHost();
 30///
 31/// await host.RunAsync();
 32/// </code>
 33/// </example>
 34[DoNotAutoRegister]
 35public sealed record HostSyringe
 36{
 11237    internal ConfiguredSyringe BaseSyringe { get; init; }
 1938    internal Func<CreateHostOptions>? OptionsFactory { get; init; }
 1139    internal Func<IServiceProviderBuilder, IServiceCollectionPopulator, IHostFactory>? HostFactoryCreator { get; init; }
 1540    internal Action<HostApplicationBuilder, CreateHostOptions>? ConfigureCallback { get; init; }
 41
 42    /// <summary>
 43    /// Initializes a new instance of the <see cref="HostSyringe"/> class.
 44    /// </summary>
 45    /// <param name="baseSyringe">The configured syringe to wrap.</param>
 46    /// <example>
 47    /// <code>
 48    /// var configuredSyringe = new Syringe().UsingReflection();
 49    ///
 50    /// var hostSyringe = new HostSyringe(configuredSyringe);
 51    /// </code>
 52    /// </example>
 2553    public HostSyringe(ConfiguredSyringe baseSyringe)
 54    {
 2555        ArgumentNullException.ThrowIfNull(baseSyringe);
 2456        BaseSyringe = baseSyringe;
 2457    }
 58
 59    /// <summary>
 60    /// Builds a host with the configured settings.
 61    /// </summary>
 62    /// <returns>The configured <see cref="IHost"/>.</returns>
 63    /// <example>
 64    /// <code>
 65    /// var host = new Syringe()
 66    ///     .UsingReflection()
 67    ///     .UsingScrutorTypeRegistrar()
 68    ///     .ForHost()
 69    ///     .UsingOptions(() => CreateHostOptions.Default
 70    ///         .UsingArgs(args)
 71    ///         .UsingApplicationName("My Worker Service"))
 72    ///     .UsingConfigurationCallback((builder, options) =>
 73    ///     {
 74    ///         // Add custom configuration sources
 75    ///         builder.Configuration.AddJsonFile("appsettings.local.json", optional: true);
 76    ///
 77    ///         // Register additional services
 78    ///         builder.Services.AddSingleton&lt;ICustomService, CustomService&gt;();
 79    ///     })
 80    ///     .BuildHost();
 81    ///
 82    /// await host.RunAsync();
 83    /// </code>
 84    /// </example>
 85    public IHost BuildHost()
 86    {
 1187        var typeRegistrar = BaseSyringe.GetOrCreateTypeRegistrar();
 1188        var typeFilterer = BaseSyringe.GetOrCreateTypeFilterer();
 1189        var pluginFactory = BaseSyringe.GetOrCreatePluginFactory();
 1190        var serviceCollectionPopulator = BaseSyringe.GetOrCreateServiceCollectionPopulator(typeRegistrar, typeFilterer, 
 1191        var assemblyProvider = BaseSyringe.GetOrCreateAssemblyProvider();
 1192        var additionalAssemblies = BaseSyringe.GetAdditionalAssemblies();
 1193        var callbacks = ConfiguredSyringe.ComposePostPluginRegistrationCallbacks(
 1194            BaseSyringe.GetPostPluginRegistrationCallbacks(),
 1195            services => ConfiguredSyringe.GetRequiredRegisteredConfiguration(
 1196                services,
 1197                nameof(HostSyringe)));
 98
 1199        var serviceProviderBuilder = BaseSyringe.GetOrCreateServiceProviderBuilder(
 11100            serviceCollectionPopulator,
 11101            assemblyProvider,
 11102            additionalAssemblies);
 103
 11104        var hostFactory = GetOrCreateHostFactory(serviceProviderBuilder, serviceCollectionPopulator, pluginFactory);
 11105        var options = GetOrCreateOptions();
 11106        if (callbacks.Count > 0)
 107        {
 0108            options = options.UsingPostPluginRegistrationCallbacks(callbacks);
 109        }
 110
 11111        return hostFactory.Create(
 11112            options,
 11113            ConfigureCallback);
 114    }
 115
 116    /// <summary>
 117    /// Builds a service provider with the configured settings.
 118    /// </summary>
 119    /// <param name="config">The configuration to use for building the service provider.</param>
 120    /// <returns>The configured <see cref="IServiceProvider"/>.</returns>
 121    /// <example>
 122    /// <code>
 123    /// var config = new ConfigurationBuilder()
 124    ///     .AddJsonFile("appsettings.json")
 125    ///     .Build();
 126    ///
 127    /// var serviceProvider = new Syringe()
 128    ///     .UsingReflection()
 129    ///     .UsingScrutorTypeRegistrar()
 130    ///     .ForHost()
 131    ///     .BuildServiceProvider(config);
 132    ///
 133    /// var myService = serviceProvider.GetRequiredService&lt;IMyService&gt;();
 134    /// </code>
 135    /// </example>
 136    public IServiceProvider BuildServiceProvider(IConfiguration config)
 137    {
 0138        return BaseSyringe.BuildServiceProvider(config);
 139    }
 140
 141    private IHostFactory GetOrCreateHostFactory(
 142        IServiceProviderBuilder serviceProviderBuilder,
 143        IServiceCollectionPopulator serviceCollectionPopulator,
 144        IPluginFactory pluginFactory)
 145    {
 11146        return HostFactoryCreator?.Invoke(serviceProviderBuilder, serviceCollectionPopulator)
 11147            ?? new HostFactory(serviceProviderBuilder, serviceCollectionPopulator, pluginFactory);
 148    }
 149
 150    private CreateHostOptions GetOrCreateOptions()
 151    {
 11152        return OptionsFactory?.Invoke() ?? CreateHostOptions.Default;
 153    }
 154}