using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
public static void Main()
var container = new ServiceCollection();
container.Configure<MyOptions>(o => new MyOptions{DirectoryPath = ""});
container.AddTransient<IValidateOptions<MyOptions>, MyOptionsValidator>();
container.AddLogging(b => b.AddConsole().AddFileLogger());
using (var scope = container.BuildServiceProvider().CreateScope())
var sp = scope.ServiceProvider;
var logger = sp.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Working...");
var validator = sp.GetRequiredService<IValidateOptions<MyOptions>>();
validator.Validate("test", new MyOptions{});
public interface IValidateOptions<T>
bool Validate(string name, T options);
public class MyOptionsValidator : IValidateOptions<MyOptions>
private readonly ILoggerFactory _loggerFactory;
_logger = _loggerFactory.CreateLogger(GetType());
public MyOptionsValidator(ILoggerFactory loggerFactory)
_loggerFactory = loggerFactory;
public bool Validate(string name, MyOptions myOptions)
if (string.IsNullOrEmpty(myOptions.DirectoryPath) || string.IsNullOrEmpty(myOptions.FileName))
Logger.LogWarning("Invalid");
public string DirectoryPath
internal class FileLogger : ILogger
private readonly string fullLogFilePath;
public FileLogger(string logDirectoryPath, string logFileName)
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
if (!IsEnabled(logLevel))
Console.WriteLine($"[{DateTime.Now}] [{logLevel}] {formatter(state, exception)} {exception?.StackTrace}");
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
public IDisposable BeginScope<TState>(TState state) => null;
internal class FileLoggerProvider : ILoggerProvider
private readonly IOptionsMonitor<MyOptions> myOptionsMonitor;
public FileLoggerProvider(IOptionsMonitor<MyOptions> myOptionsMonitor)
this.myOptionsMonitor = myOptionsMonitor;
public ILogger CreateLogger(string categoryName)
MyOptions myOptions = myOptionsMonitor.CurrentValue;
return new FileLogger(myOptions.DirectoryPath, myOptions.FileName);
public static class ILoggingBuilderExtensions
public static void AddFileLogger(this ILoggingBuilder loggingBuilder)
loggingBuilder.Services.AddSingleton<ILoggerProvider, FileLoggerProvider>();