ProfK
ProfK

Reputation: 51064

Exception when calling ServiceProvider.GetRequiredService in a .NET 5.0 console app

I have pieced together the following code in my Program class, after a few hours trying to find info on DI and logging in a .NET 5.0 console app. Such info is very scarce compared to info on a web app:

private static void BuildConfig(IConfigurationBuilder builder)
{
    builder.SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
        .AddEnvironmentVariables();
}

private static void ConfigureServices(ServiceCollection serviceCollection, ILogger logger)
{
    serviceCollection
        .AddLogging(builder => builder.AddSerilog(logger))
        .AddSingleton<ApplicationService>();
}

public static async Task<int> Main(string[] args)
{
    // Setup config
    var builder = new ConfigurationBuilder();
    BuildConfig(builder);

    // Setup logging
    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(builder.Build())
        .CreateLogger();

    // Setup Dependency Injection         
    var serviceCollection = new ServiceCollection();
    ConfigureServices(serviceCollection, Log.Logger);
    var serviceProvider = serviceCollection.BuildServiceProvider();

    // Use dependency injection
    var applicationService = serviceProvider.GetRequiredService<ApplicationService>();

    var runResult = await applicationService.RunAsync(args);
    return runResult;
}

When I try and run my app I get the following error:

System.InvalidOperationException: 'Unable to resolve service for type 'Serilog.ILogger' while attempting to activate 'DalBuilder.Lib.ApplicationService'.'

Upvotes: 1

Views: 484

Answers (1)

Nkosi
Nkosi

Reputation: 247163

Most likely using wrong logger in ApplicationService constructor.

Refactor to use built-in logger ILogger<ApplicationService>

//...

private readonly ILogger logger; //<-- use build-in logger

public ApplicationService(ILogger<ApplicationService> logger, ....) {

    this.logger = logger;

    //...
}

This configuration of the logger

//...

.AddLogging(builder => builder.AddSerilog(logger))

//...

is basically wrapping the Serilog logger within the built-in logger.

Upvotes: 2

Related Questions