diff --git a/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs b/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs index 9bb66887ef..5a193615d0 100644 --- a/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs +++ b/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs @@ -33,8 +33,9 @@ public static ILoggingBuilder AddDynamicConsole(this ILoggingBuilder builder) UpdateConsoleLoggerProviderRegistration(builder.Services); builder.AddFilter(null, LogLevel.Trace); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - builder.Services.AddSingleton(provider => provider.GetServices().OfType().Single()); + builder.Services.TryAddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); DisableConsoleColorsOnCloudPlatform(builder); } diff --git a/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs b/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs index c01090d0ca..0041a8c83f 100644 --- a/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs +++ b/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Serilog; -using Steeltoe.Common; namespace Steeltoe.Logging.DynamicSerilog; @@ -94,8 +93,9 @@ public static ILoggingBuilder AddDynamicSerilog(this ILoggingBuilder builder, Lo ConfigureSerilogOptions(builder, serilogConfiguration); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - builder.Services.AddSingleton(provider => provider.GetServices().OfType().Single()); + builder.Services.TryAddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); } return builder; @@ -103,8 +103,7 @@ public static ILoggingBuilder AddDynamicSerilog(this ILoggingBuilder builder, Lo private static bool IsSerilogDynamicLoggerProviderAlreadyRegistered(ILoggingBuilder builder) { - return builder.Services.Any(descriptor => - descriptor.SafeGetImplementationType() == typeof(DynamicSerilogLoggerProvider) && descriptor.ServiceType == typeof(ILoggerProvider)); + return builder.Services.Any(descriptor => descriptor.ServiceType == typeof(DynamicSerilogLoggerProvider)); } private static void AssertNoDynamicLoggerProviderRegistered(ILoggingBuilder builder) diff --git a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs index 0244891b5d..c96a1a5bf5 100644 --- a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Options; using Steeltoe.Common.Logging; @@ -53,6 +54,21 @@ public async Task DoesNotRegisterWhenOtherDynamicProviderIsAlreadyRegistered() host.Services.GetServices().Should().NotContain(provider => provider is DynamicConsoleLoggerProvider); } + [Fact] + public async Task CanUseThirdPartyDynamicLoggerProvider() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Logging.AddDynamicConsole(); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().ContainSingle(); + host.Services.GetServices().Should().NotContain(provider => provider is DynamicConsoleLoggerProvider); + } + [Fact] public async Task CanChangeMinimumLogLevels() { @@ -203,11 +219,23 @@ public async Task DisposeTwiceSucceeds() action.Should().NotThrow(); } + [Fact] + public async Task DoesNotCrashWhenLoggingProvidersAreCleared() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Logging.AddDynamicConsole(); + builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders()); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().BeEmpty(); + } + private sealed class OtherDynamicLoggerProvider : IDynamicLoggerProvider { public ILogger CreateLogger(string categoryName) { - throw new NotSupportedException(); + return NullLogger.Instance; } public ICollection GetLogLevels() diff --git a/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs b/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs index 151b001ca2..714f1c7fc1 100644 --- a/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs @@ -403,6 +403,18 @@ public async Task DisposeTwiceSucceeds() action.Should().NotThrow(); } + [Fact] + public async Task DoesNotCrashWhenLoggingProvidersAreCleared() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Logging.AddDynamicSerilog(); + builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders()); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().BeEmpty(); + } + public void Dispose() { _consoleOutput.Dispose();