Skip to content

Expose IServiceProvider on inline initialization delegate #177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 65 additions & 15 deletions src/Serilog.AspNetCore/SerilogWebHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,26 @@ public static IWebHostBuilder UseSerilog(
{
if (builder == null) throw new ArgumentNullException(nameof(builder));

builder.ConfigureServices(collection =>
builder.ConfigureServices(services =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

{
if (providers != null)
{
collection.AddSingleton<ILoggerFactory>(services =>
services.AddSingleton<ILoggerFactory>(serviceProvider =>
{
var factory = new SerilogLoggerFactory(logger, dispose, providers);

foreach (var provider in services.GetServices<ILoggerProvider>())
foreach (var provider in serviceProvider.GetServices<ILoggerProvider>())
factory.AddProvider(provider);

return factory;
});
}
else
{
collection.AddSingleton<ILoggerFactory>(services => new SerilogLoggerFactory(logger, dispose));
services.AddSingleton<ILoggerFactory>(serviceProvider => new SerilogLoggerFactory(logger, dispose));
}

ConfigureServices(collection, logger);
ConfigureServices(services, logger);
});

return builder;
Expand All @@ -92,7 +92,7 @@ public static IWebHostBuilder UseSerilog(
if (builder == null) throw new ArgumentNullException(nameof(builder));
if (configureLogger == null) throw new ArgumentNullException(nameof(configureLogger));

builder.ConfigureServices((context, collection) =>
builder.ConfigureServices((context, services) =>
{
var loggerConfiguration = new LoggerConfiguration();

Expand All @@ -118,42 +118,92 @@ public static IWebHostBuilder UseSerilog(
Log.Logger = logger;
}

collection.AddSingleton<ILoggerFactory>(services =>
services.AddSingleton<ILoggerFactory>(serviceProvider =>
{
var factory = new SerilogLoggerFactory(registeredLogger, true, loggerProviders);

if (writeToProviders)
{
foreach (var provider in services.GetServices<ILoggerProvider>())
foreach (var provider in serviceProvider.GetServices<ILoggerProvider>())
factory.AddProvider(provider);
}

return factory;
});

ConfigureServices(collection, logger);
ConfigureServices(services, logger);
});
return builder;
}

static void ConfigureServices(IServiceCollection collection, ILogger logger)

/// <summary>Sets Serilog as the logging provider.</summary>
/// <remarks>
/// A <see cref="WebHostBuilderContext"/> is supplied so that configuration and hosting information can be used.
/// The logger will be shut down when application services are disposed.
/// </remarks>
/// <param name="builder">The web host builder to configure.</param>
/// <param name="configureLogger">The delegate for configuring the <see cref="LoggerConfiguration" /> that will be used to construct a <see cref="Logger" />.</param>
/// <param name="writeToProviders">By default, Serilog does not write events to <see cref="ILoggerProvider"/>s registered through
/// the Microsoft.Extensions.Logging API. Normally, equivalent Serilog sinks are used in place of providers. Specify
/// <c>true</c> to write events to all providers.</param>
/// <returns>The web host builder.</returns>
public static IWebHostBuilder UseSerilog(
this IWebHostBuilder builder,
Action<WebHostBuilderContext, LoggerConfiguration, IServiceProvider> configureLogger,
bool writeToProviders = false)
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
if (configureLogger == null) throw new ArgumentNullException(nameof(configureLogger));

builder.ConfigureServices((webHostBuilderContext, services) =>
{
services.AddSingleton<ILoggerFactory>(serviceProvider =>
{
var loggerConfiguration = new LoggerConfiguration();

LoggerProviderCollection loggerProviders = null;
if (writeToProviders)
{
loggerProviders = new LoggerProviderCollection();
loggerConfiguration.WriteTo.Providers(loggerProviders);
}

configureLogger(webHostBuilderContext, loggerConfiguration, serviceProvider);

var loggerFactory = new SerilogLoggerFactory(
loggerConfiguration.CreateLogger(),
providerCollection: loggerProviders);

if (writeToProviders)
{
foreach (var provider in serviceProvider.GetServices<ILoggerProvider>())
loggerFactory.AddProvider(provider);
}

return loggerFactory;
});
});
return builder;
}

static void ConfigureServices(IServiceCollection services, ILogger logger)
{
if (collection == null) throw new ArgumentNullException(nameof(collection));
if (services == null) throw new ArgumentNullException(nameof(services));

if (logger != null)
{
// This won't (and shouldn't) take ownership of the logger.
collection.AddSingleton(logger);
services.AddSingleton(logger);
}

// Registered to provide two services...
var diagnosticContext = new DiagnosticContext(logger);

// Consumed by e.g. middleware
collection.AddSingleton(diagnosticContext);
services.AddSingleton(diagnosticContext);

// Consumed by user code
collection.AddSingleton<IDiagnosticContext>(diagnosticContext);
services.AddSingleton<IDiagnosticContext>(diagnosticContext);
}
}
}