ILogger Dependency Injection for Libraries
The below is what I came up with to inject a logger into a library, but something feels off. Can anyone advise if something in my approach needs tweaking?
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace LogInjection;
class Program
{
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {SourceContext}] {Message:lj}{NewLine}{Exception}"
)
.CreateLogger();
using ServiceProvider serviceProvider = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true))
.AddSingleton<FooFactory>()
.BuildServiceProvider();
var fooFactory = serviceProvider.GetRequiredService<FooFactory>();
fooFactory.CreateFoo("red").DoSomething();
fooFactory.CreateFoo("blue").DoSomething();
}
}
// Library code here
public class FooService { }
public class FooFactory(ILogger<FooService>? logger = null)
{
private readonly ILogger _logger = logger ?? NullLogger<FooService>.Instance;
public IFoo CreateFoo(string type)
{
_logger.LogInformation("Creating a new {Type}", type);
return type switch
{
"red" => new FooRed(_logger),
"blue" => new FooBlue(_logger),
_ => throw new ArgumentException("Unknown type", nameof(type)),
};
}
}
public interface IFoo
{
void DoSomething();
}
internal class FooRed(ILogger logger) : IFoo
{
public void DoSomething()
{
logger.LogInformation("I'm red!");
}
}
internal class FooBlue(ILogger logger) : IFoo
{
public void DoSomething()
{
logger.LogInformation("I'm blue!");
}
}using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace LogInjection;
class Program
{
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {SourceContext}] {Message:lj}{NewLine}{Exception}"
)
.CreateLogger();
using ServiceProvider serviceProvider = new ServiceCollection()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true))
.AddSingleton<FooFactory>()
.BuildServiceProvider();
var fooFactory = serviceProvider.GetRequiredService<FooFactory>();
fooFactory.CreateFoo("red").DoSomething();
fooFactory.CreateFoo("blue").DoSomething();
}
}
// Library code here
public class FooService { }
public class FooFactory(ILogger<FooService>? logger = null)
{
private readonly ILogger _logger = logger ?? NullLogger<FooService>.Instance;
public IFoo CreateFoo(string type)
{
_logger.LogInformation("Creating a new {Type}", type);
return type switch
{
"red" => new FooRed(_logger),
"blue" => new FooBlue(_logger),
_ => throw new ArgumentException("Unknown type", nameof(type)),
};
}
}
public interface IFoo
{
void DoSomething();
}
internal class FooRed(ILogger logger) : IFoo
{
public void DoSomething()
{
logger.LogInformation("I'm red!");
}
}
internal class FooBlue(ILogger logger) : IFoo
{
public void DoSomething()
{
logger.LogInformation("I'm blue!");
}
}