| | | 1 | | using Microsoft.Extensions.Configuration; |
| | | 2 | | using Microsoft.Extensions.Logging; |
| | | 3 | | |
| | | 4 | | namespace NexusLabs.Needlr.Hosting; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// Extension methods for configuring <see cref="NeedlrBootstrapper"/> instances. |
| | | 8 | | /// </summary> |
| | | 9 | | public static class NeedlrBootstrapperExtensions |
| | | 10 | | { |
| | | 11 | | /// <summary> |
| | | 12 | | /// Overrides the default console logger factory with a custom <see cref="ILoggerFactory"/>. |
| | | 13 | | /// </summary> |
| | | 14 | | /// <param name="bootstrapper">The bootstrapper to configure.</param> |
| | | 15 | | /// <param name="loggerFactory">The logger factory to use.</param> |
| | | 16 | | /// <returns>A new <see cref="NeedlrBootstrapper"/> with the factory applied.</returns> |
| | | 17 | | /// <example> |
| | | 18 | | /// <code> |
| | | 19 | | /// await new NeedlrBootstrapper() |
| | | 20 | | /// .UsingLoggerFactory(myLoggerFactory) |
| | | 21 | | /// .RunAsync(async (ctx, ct) => { /* ... */ }); |
| | | 22 | | /// </code> |
| | | 23 | | /// </example> |
| | | 24 | | public static NeedlrBootstrapper UsingLoggerFactory( |
| | | 25 | | this NeedlrBootstrapper bootstrapper, |
| | | 26 | | ILoggerFactory loggerFactory) |
| | | 27 | | { |
| | 30 | 28 | | ArgumentNullException.ThrowIfNull(bootstrapper); |
| | 29 | 29 | | ArgumentNullException.ThrowIfNull(loggerFactory); |
| | 28 | 30 | | return bootstrapper with { Factory = loggerFactory }; |
| | | 31 | | } |
| | | 32 | | |
| | | 33 | | /// <summary> |
| | | 34 | | /// Registers an async cleanup callback that runs in the <c>finally</c> block of |
| | | 35 | | /// <see cref="NeedlrBootstrapper.RunAsync"/>, regardless of whether the application |
| | | 36 | | /// succeeds or throws. |
| | | 37 | | /// </summary> |
| | | 38 | | /// <param name="bootstrapper">The bootstrapper to configure.</param> |
| | | 39 | | /// <param name="cleanup">The async cleanup delegate (e.g. flushing a log sink).</param> |
| | | 40 | | /// <returns>A new <see cref="NeedlrBootstrapper"/> with the cleanup registered.</returns> |
| | | 41 | | /// <example> |
| | | 42 | | /// <code> |
| | | 43 | | /// await new NeedlrBootstrapper() |
| | | 44 | | /// .WithCleanup(async () => await FlushLogsAsync()) |
| | | 45 | | /// .RunAsync(async (ctx, ct) => { /* ... */ }); |
| | | 46 | | /// </code> |
| | | 47 | | /// </example> |
| | | 48 | | public static NeedlrBootstrapper WithCleanup( |
| | | 49 | | this NeedlrBootstrapper bootstrapper, |
| | | 50 | | Func<Task> cleanup) |
| | | 51 | | { |
| | 19 | 52 | | ArgumentNullException.ThrowIfNull(bootstrapper); |
| | 18 | 53 | | ArgumentNullException.ThrowIfNull(cleanup); |
| | 17 | 54 | | return bootstrapper with { Cleanup = cleanup }; |
| | | 55 | | } |
| | | 56 | | |
| | | 57 | | /// <summary> |
| | | 58 | | /// Configures the bootstrap-phase <see cref="IConfiguration"/> by adding sources to the |
| | | 59 | | /// <see cref="IConfigurationBuilder"/>. |
| | | 60 | | /// </summary> |
| | | 61 | | /// <remarks> |
| | | 62 | | /// <para> |
| | | 63 | | /// The bootstrap configuration is <strong>not</strong> the same <see cref="IConfiguration"/> |
| | | 64 | | /// that the application's DI container will provide. It exists only for the duration of the |
| | | 65 | | /// bootstrap callback and is disposed after <see cref="NeedlrBootstrapper.RunAsync"/> completes. |
| | | 66 | | /// Syringe (and the .NET Generic Host / WebApplication builder) builds its own |
| | | 67 | | /// <see cref="IConfiguration"/> independently. |
| | | 68 | | /// </para> |
| | | 69 | | /// <para> |
| | | 70 | | /// By default the bootstrap configuration is <strong>empty</strong>. Call this method to add |
| | | 71 | | /// JSON files, environment variables, in-memory collections, or any other |
| | | 72 | | /// <see cref="IConfigurationSource"/> needed during the bootstrap phase. |
| | | 73 | | /// </para> |
| | | 74 | | /// <para> |
| | | 75 | | /// If called multiple times, only the last call takes effect. |
| | | 76 | | /// </para> |
| | | 77 | | /// </remarks> |
| | | 78 | | /// <param name="bootstrapper">The bootstrapper to configure.</param> |
| | | 79 | | /// <param name="configure"> |
| | | 80 | | /// A delegate that adds configuration sources to the <see cref="IConfigurationBuilder"/>. |
| | | 81 | | /// </param> |
| | | 82 | | /// <returns>A new <see cref="NeedlrBootstrapper"/> with the configuration builder registered.</returns> |
| | | 83 | | /// <example> |
| | | 84 | | /// <code> |
| | | 85 | | /// await new NeedlrBootstrapper() |
| | | 86 | | /// .ConfigureBootstrapConfiguration(builder => builder |
| | | 87 | | /// .AddJsonFile("appsettings.json", optional: true) |
| | | 88 | | /// .AddEnvironmentVariables()) |
| | | 89 | | /// .RunAsync(async (ctx, ct) => |
| | | 90 | | /// { |
| | | 91 | | /// var logDir = ctx.BootstrapConfiguration["Logging:Directory"] |
| | | 92 | | /// ?? "logs"; |
| | | 93 | | /// ctx.Logger.LogInformation("Bootstrap log directory: {Dir}", logDir); |
| | | 94 | | /// }); |
| | | 95 | | /// </code> |
| | | 96 | | /// </example> |
| | | 97 | | public static NeedlrBootstrapper ConfigureBootstrapConfiguration( |
| | | 98 | | this NeedlrBootstrapper bootstrapper, |
| | | 99 | | Action<IConfigurationBuilder> configure) |
| | | 100 | | { |
| | 10 | 101 | | ArgumentNullException.ThrowIfNull(bootstrapper); |
| | 9 | 102 | | ArgumentNullException.ThrowIfNull(configure); |
| | 8 | 103 | | return bootstrapper with { ConfigureBootstrapConfigurationBuilder = configure }; |
| | | 104 | | } |
| | | 105 | | } |