77using System . Diagnostics ;
88using System . Collections . Generic ;
99using Microsoft . Extensions . DependencyInjection ;
10+ using Microsoft . Extensions . Logging . Abstractions ;
1011using Moq ;
1112using Xunit ;
1213
@@ -20,7 +21,7 @@ public void AddProvider_ThrowsAfterDisposed()
2021 var factory = new LoggerFactory ( ) ;
2122 factory . Dispose ( ) ;
2223
23- Assert . Throws < ObjectDisposedException > ( ( ) => ( ( ILoggerFactory ) factory ) . AddProvider ( CreateProvider ( ) ) ) ;
24+ Assert . Throws < ObjectDisposedException > ( ( ) => ( ( ILoggerFactory ) factory ) . AddProvider ( CreateProvider ( ) ) ) ;
2425 }
2526
2627 [ Fact ]
@@ -214,7 +215,7 @@ public void TestActivityIds(ActivityTrackingOptions options)
214215 public void TestInvalidActivityTrackingOptions ( )
215216 {
216217 Assert . Throws < ArgumentException > ( ( ) =>
217- LoggerFactory . Create ( builder => { builder . Configure ( o => o . ActivityTrackingOptions = ( ActivityTrackingOptions ) 0xFF00 ) ; } )
218+ LoggerFactory . Create ( builder => { builder . Configure ( o => o . ActivityTrackingOptions = ( ActivityTrackingOptions ) 0xFF00 ) ; } )
218219 ) ;
219220 }
220221
@@ -434,7 +435,7 @@ public void BaggageFormattedOutput()
434435 }
435436 activity . Stop ( ) ;
436437
437- string [ ] loggerOutput = new string [ ]
438+ string [ ] loggerOutput = new string [ ]
438439 {
439440 $ "Inside Scope Info!",
440441 $ "[TraceId, { activity . GetTraceId ( ) } ]",
@@ -451,7 +452,7 @@ public void BaggageFormattedOutput()
451452 public void CallsSetScopeProvider_OnSupportedProviders ( )
452453 {
453454 var loggerProvider = new ExternalScopeLoggerProvider ( ) ;
454- var loggerFactory = new LoggerFactory ( new [ ] { loggerProvider } ) ;
455+ var loggerFactory = new LoggerFactory ( new [ ] { loggerProvider } ) ;
455456
456457 var logger = loggerFactory . CreateLogger ( "Logger" ) ;
457458
@@ -480,7 +481,7 @@ public void CallsSetScopeProvider_OnSupportedProviders()
480481 public void BeginScope_ReturnsExternalSourceTokenDirectly ( )
481482 {
482483 var loggerProvider = new ExternalScopeLoggerProvider ( ) ;
483- var loggerFactory = new LoggerFactory ( new [ ] { loggerProvider } ) ;
484+ var loggerFactory = new LoggerFactory ( new [ ] { loggerProvider } ) ;
484485
485486 var logger = loggerFactory . CreateLogger ( "Logger" ) ;
486487
@@ -503,7 +504,7 @@ public void BeginScope_ReturnsCompositeToken_ForMultipleLoggers()
503504 {
504505 var loggerProvider = new ExternalScopeLoggerProvider ( ) ;
505506 var loggerProvider2 = new InternalScopeLoggerProvider ( ) ;
506- var loggerFactory = new LoggerFactory ( new ILoggerProvider [ ] { loggerProvider , loggerProvider2 } ) ;
507+ var loggerFactory = new LoggerFactory ( new ILoggerProvider [ ] { loggerProvider , loggerProvider2 } ) ;
507508
508509 var logger = loggerFactory . CreateLogger ( "Logger" ) ;
509510
@@ -543,12 +544,57 @@ public void CreateDisposeDisposesInnerServiceProvider()
543544 var provider = new Mock < ILoggerProvider > ( ) ;
544545 provider . Setup ( p => p . Dispose ( ) ) . Callback ( ( ) => disposed = true ) ;
545546
546- var factory = LoggerFactory . Create ( builder => builder . Services . AddSingleton ( _=> provider . Object ) ) ;
547+ var factory = LoggerFactory . Create ( builder => builder . Services . AddSingleton ( _ => provider . Object ) ) ;
547548 factory . Dispose ( ) ;
548549
549550 Assert . True ( disposed ) ;
550551 }
551552
553+ // Moq heavily utilizes RefEmit, which does not work on most aot workloads
554+ [ ConditionalFact ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsReflectionEmitSupported ) ) ]
555+ public void TestCreateLoggers_NullLoggerIsIgnoredWhenReturnedByProvider ( )
556+ {
557+ // We test this via checking if Scope optimisaion (ie not return scope wrapper but the
558+ // returned scope directly only one logger) is applied.
559+ var nullProvider = new Mock < ILoggerProvider > ( ) ;
560+ nullProvider . Setup ( p => p . CreateLogger ( It . IsAny < string > ( ) ) ) . Returns ( NullLogger . Instance ) ;
561+
562+ var validProvider = new CustomScopeLoggerProvider ( ) ;
563+
564+ var factory = LoggerFactory . Create ( builder =>
565+ {
566+ builder . AddProvider ( nullProvider . Object ) ;
567+ builder . AddProvider ( validProvider ) ;
568+ } ) ;
569+ var logger = factory . CreateLogger ( "TestLogger" ) ;
570+
571+ var scope = logger . BeginScope ( "TestScope" ) ;
572+ Assert . IsType < CustomScopeLoggerProvider . CustomScope > ( scope ) ;
573+
574+ logger . LogInformation ( "Test message" ) ;
575+ Assert . Equal ( 1 , validProvider . LogText . Count ) ;
576+ }
577+
578+ private class CustomScopeLoggerProvider : ILoggerProvider , ILogger
579+ {
580+ public List < string > LogText { get ; set ; } = new List < string > ( ) ;
581+
582+ public void Dispose ( ) { }
583+
584+ public ILogger CreateLogger ( string categoryName ) => this ;
585+
586+ public void Log < TState > ( LogLevel logLevel , EventId eventId , TState state , Exception exception , Func < TState , Exception , string > formatter ) => LogText . Add ( formatter ( state , exception ) ) ;
587+
588+ public bool IsEnabled ( LogLevel logLevel ) => true ;
589+
590+ public IDisposable BeginScope < TState > ( TState state ) => new CustomScope ( ) ;
591+
592+ internal class CustomScope : IDisposable
593+ {
594+ public void Dispose ( ) { }
595+ }
596+ }
597+
552598 private class InternalScopeLoggerProvider : ILoggerProvider , ILogger
553599 {
554600 private IExternalScopeProvider _scopeProvider = new LoggerExternalScopeProvider ( ) ;
0 commit comments