diff --git a/source/FileLogger.Json/JsonFileLoggerExtensions.cs b/source/FileLogger.Json/JsonFileLoggerExtensions.cs index 84c1fc3..ff5df23 100644 --- a/source/FileLogger.Json/JsonFileLoggerExtensions.cs +++ b/source/FileLogger.Json/JsonFileLoggerExtensions.cs @@ -99,11 +99,16 @@ public static ILoggingBuilder AddJsonFile< Action? configure = null, string? optionsName = null) where TProvider : FileLoggerProvider { + if (builder is null) + throw new ArgumentNullException(nameof(builder)); + + optionsName ??= typeof(TProvider).ToString(); + builder.AddFile(context, configure: null, optionsName) - .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName ?? typeof(TProvider).ToString()); + .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName); if (configure is not null) - builder.Services.Configure(configure); + builder.Services.Configure(optionsName, configure); return builder; } @@ -125,11 +130,16 @@ public static ILoggingBuilder AddJsonFile< where TProvider : FileLoggerProvider where TOptions : FileLoggerOptions { + if (builder is null) + throw new ArgumentNullException(nameof(builder)); + + optionsName ??= typeof(TProvider).ToString(); + builder.AddFile(context, configure: null, optionsName) - .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName ?? typeof(TProvider).ToString()); + .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName); if (configure is not null) - builder.Services.Configure(configure); + builder.Services.Configure(optionsName, configure); return builder; } @@ -145,11 +155,16 @@ public static ILoggingBuilder AddJsonFile< where TProvider : FileLoggerProvider where TOptions : FileLoggerOptions { + if (builder is null) + throw new ArgumentNullException(nameof(builder)); + + optionsName ??= typeof(TProvider).ToString(); + builder.AddFile(bindOptions, context, configure: null, optionsName) - .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName ?? typeof(TProvider).ToString()); + .ConfigureTextBuilder(textBuilder ?? JsonFileLogEntryTextBuilder.Default, optionsName); if (configure is not null) - builder.Services.Configure(configure); + builder.Services.Configure(optionsName, configure); return builder; } diff --git a/test/FileLogger.Test/SettingsTest.cs b/test/FileLogger.Test/SettingsTest.cs index 3868467..e9e10e4 100644 --- a/test/FileLogger.Test/SettingsTest.cs +++ b/test/FileLogger.Test/SettingsTest.cs @@ -381,4 +381,54 @@ static string BuildConfigJson(LogLevel defaultProviderLevel, LogLevel otherProvi "" }, lines); } + + private static void AssertUserConfigurationAppliesToNamedOptions( + Action configureLogging, string optionsName, string expectedBasePath) + { + var services = new ServiceCollection(); + services.AddLogging(configureLogging); + + using ServiceProvider serviceProvider = services.BuildServiceProvider(); + + // The provider resolves its settings via IOptionsMonitor.Get(optionsName), so the user + // configuration callback must be applied to the named options instance, not Options.DefaultName. + IOptionsMonitor optionsMonitor = + serviceProvider.GetRequiredService>(); + + Assert.Equal(expectedBasePath, optionsMonitor.Get(optionsName).BasePath); + Assert.NotEqual(expectedBasePath, optionsMonitor.Get(Options.DefaultName).BasePath); + } + + [Fact] + public void Issue39_GenericAddJsonFileAppliesUserConfigurationToNamedOptions() + { + const string optionsName = "MyJsonProvider"; + const string basePath = "some-sentinel-base-path"; + + AssertUserConfigurationAppliesToNamedOptions( + lb => lb.AddJsonFile(configure: o => o.BasePath = basePath, optionsName: optionsName), + optionsName, basePath); + } + + [Fact] + public void Issue39_GenericAddJsonFileWithOptionsAppliesUserConfigurationToNamedOptions() + { + const string optionsName = "MyJsonProvider"; + const string basePath = "some-sentinel-base-path"; + + AssertUserConfigurationAppliesToNamedOptions( + lb => lb.AddJsonFile(configure: o => o.BasePath = basePath, optionsName: optionsName), + optionsName, basePath); + } + + [Fact] + public void Issue39_GenericAddJsonFileWithBindOptionsAppliesUserConfigurationToNamedOptions() + { + const string optionsName = "MyJsonProvider"; + const string basePath = "some-sentinel-base-path"; + + AssertUserConfigurationAppliesToNamedOptions( + lb => lb.AddJsonFile(bindOptions: (o, c) => { }, configure: o => o.BasePath = basePath, optionsName: optionsName), + optionsName, basePath); + } }