1313// limitations under the License.
1414
1515using System ;
16- using Microsoft . Extensions . DependencyInjection ;
1716using Microsoft . Extensions . Hosting ;
1817using Microsoft . Extensions . Logging ;
19- using Serilog . Extensions . Hosting ;
2018using Serilog . Extensions . Logging ;
2119// ReSharper disable MemberCanBePrivate.Global
2220
@@ -27,20 +25,6 @@ namespace Serilog
2725 /// </summary>
2826 public static class SerilogHostBuilderExtensions
2927 {
30- // Used internally to pass information through the container. We need to do this because if `logger` is the
31- // root logger, registering it as a singleton may lead to disposal along with the container by MEDI. This isn't
32- // always desirable, i.e. we may be handed a logger and `dispose: false`, so wrapping it keeps us in control
33- // of when the logger is disposed.
34- class RegisteredLogger
35- {
36- public RegisteredLogger ( ILogger logger )
37- {
38- Logger = logger ;
39- }
40-
41- public ILogger Logger { get ; }
42- }
43-
4428 /// <summary>
4529 /// Sets Serilog as the logging provider.
4630 /// </summary>
@@ -63,33 +47,7 @@ public static IHostBuilder UseSerilog(
6347
6448 builder . ConfigureServices ( ( _ , collection ) =>
6549 {
66- if ( providers != null )
67- {
68- collection . AddSingleton < ILoggerFactory > ( services =>
69- {
70- var factory = new SerilogLoggerFactory ( logger , dispose , providers ) ;
71-
72- foreach ( var provider in services . GetServices < ILoggerProvider > ( ) )
73- factory . AddProvider ( provider ) ;
74-
75- return factory ;
76- } ) ;
77- }
78- else
79- {
80- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , dispose ) ) ;
81- }
82-
83- if ( logger != null )
84- {
85- // This won't (and shouldn't) take ownership of the logger.
86- collection . AddSingleton ( logger ) ;
87-
88- // Still need to use RegisteredLogger as it is used by ConfigureDiagnosticContext.
89- collection . AddSingleton ( new RegisteredLogger ( logger ) ) ;
90- }
91- bool useRegisteredLogger = logger != null ;
92- ConfigureDiagnosticContext ( collection , useRegisteredLogger ) ;
50+ collection . AddSerilog ( logger , dispose , providers ) ;
9351 } ) ;
9452
9553 return builder ;
@@ -148,108 +106,16 @@ public static IHostBuilder UseSerilog(
148106 if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
149107 if ( configureLogger == null ) throw new ArgumentNullException ( nameof ( configureLogger ) ) ;
150108
151- // This check is eager; replacing the bootstrap logger after calling this method is not supported.
152- #if ! NO_RELOADABLE_LOGGER
153- var reloadable = Log . Logger as ReloadableLogger ;
154- var useReload = reloadable != null && ! preserveStaticLogger ;
155- #else
156- const bool useReload = false ;
157- #endif
158-
159109 builder . ConfigureServices ( ( context , collection ) =>
160110 {
161- LoggerProviderCollection loggerProviders = null ;
162- if ( writeToProviders )
163- {
164- loggerProviders = new LoggerProviderCollection ( ) ;
165- }
166-
167- collection . AddSingleton ( services =>
168- {
169- ILogger logger ;
170- #if ! NO_RELOADABLE_LOGGER
171- if ( useReload )
172- {
173- reloadable ! . Reload ( cfg =>
174- {
175- if ( loggerProviders != null )
176- cfg . WriteTo . Providers ( loggerProviders ) ;
177-
178- configureLogger ( context , services , cfg ) ;
179- return cfg ;
180- } ) ;
181-
182- logger = reloadable . Freeze ( ) ;
183- }
184- else
185- #endif
186- {
187- var loggerConfiguration = new LoggerConfiguration ( ) ;
188-
189- if ( loggerProviders != null )
190- loggerConfiguration . WriteTo . Providers ( loggerProviders ) ;
191-
192- configureLogger ( context , services , loggerConfiguration ) ;
193- logger = loggerConfiguration . CreateLogger ( ) ;
194- }
195-
196- return new RegisteredLogger ( logger ) ;
197- } ) ;
198-
199- collection . AddSingleton ( services =>
200- {
201- // How can we register the logger, here, but not have MEDI dispose it?
202- // Using the `NullEnricher` hack to prevent disposal.
203- var logger = services . GetRequiredService < RegisteredLogger > ( ) . Logger ;
204- return logger . ForContext ( new NullEnricher ( ) ) ;
205- } ) ;
206-
207- collection . AddSingleton < ILoggerFactory > ( services =>
208- {
209- var logger = services . GetRequiredService < RegisteredLogger > ( ) . Logger ;
210-
211- ILogger registeredLogger = null ;
212- if ( preserveStaticLogger )
213- {
214- registeredLogger = logger ;
215- }
216- else
217- {
218- // Passing a `null` logger to `SerilogLoggerFactory` results in disposal via
219- // `Log.CloseAndFlush()`, which additionally replaces the static logger with a no-op.
220- Log . Logger = logger ;
221- }
222-
223- var factory = new SerilogLoggerFactory ( registeredLogger , ! useReload , loggerProviders ) ;
224-
225- if ( writeToProviders )
226- {
227- foreach ( var provider in services . GetServices < ILoggerProvider > ( ) )
228- factory . AddProvider ( provider ) ;
229- }
230-
231- return factory ;
232- } ) ;
233-
234- ConfigureDiagnosticContext ( collection , preserveStaticLogger ) ;
111+ collection . AddSerilog (
112+ ( services , loggerConfiguration ) =>
113+ configureLogger ( context , services , loggerConfiguration ) ,
114+ preserveStaticLogger : preserveStaticLogger ,
115+ writeToProviders : writeToProviders ) ;
235116 } ) ;
236117
237118 return builder ;
238119 }
239-
240- static void ConfigureDiagnosticContext ( IServiceCollection collection , bool useRegisteredLogger )
241- {
242- if ( collection == null ) throw new ArgumentNullException ( nameof ( collection ) ) ;
243-
244- // Registered to provide two services...
245- // Consumed by e.g. middleware
246- collection . AddSingleton ( services =>
247- {
248- ILogger logger = useRegisteredLogger ? services . GetRequiredService < RegisteredLogger > ( ) . Logger : null ;
249- return new DiagnosticContext ( logger ) ;
250- } ) ;
251- // Consumed by user code
252- collection . AddSingleton < IDiagnosticContext > ( services => services . GetRequiredService < DiagnosticContext > ( ) ) ;
253- }
254120 }
255121}
0 commit comments