ca9163d9
ca9163d9

Reputation: 29227

Logging and configuration for .Net core 2.0 console application?

The following code got the errors. What's the right way to setup logging and configuration management for .Net Core 2.0 console application?

Error CS1061 'LoggerFactory' does not contain a definition for 'AddConsole' and no extension method 'AddConsole' accepting a first argument of type 'LoggerFactory' could be found (are you missing a using directive or an assembly reference?)

Error CS1503 Argument 2: cannot convert from 'Microsoft.Extensions.Configuration.IConfigurationSection' to 'System.Action'

class Program
{
    static void Main(string[] args)
    {
        var services = new ServiceCollection();
        ConfigureServices(services);
        var serviceProvider = services.BuildServiceProvider();
        var app = serviceProvider.GetService<Application>();
        Task.Run(() => app.Run()).Wait();
    }

    private static void ConfigureServices(IServiceCollection services)
    {
        ILoggerFactory loggerFactory = new LoggerFactory()
            .AddConsole() // Error!
            .AddDebug();

        services.AddSingleton(loggerFactory); // Add first my already configured instance
        services.AddLogging(); // Allow ILogger<T>

        IConfigurationRoot configuration = GetConfiguration();
        services.AddSingleton<IConfigurationRoot>(configuration);

        // Support typed Options
        services.AddOptions();
        services.Configure<MyOptions>(configuration.GetSection("MyOptions")); // Error!

        services.AddTransient<Application>();
    }

    private static IConfigurationRoot GetConfiguration()
    {
        return new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddXmlFile("App.config", optional: true).Build();
    }

    public class MyOptions
    {
        public string Name { get; set; }
    }

    public class Application
    {
        ILogger _logger;
        MyOptions _settings;

        public Application(ILogger<Application> logger, IOptions<MyOptions> settings)
        {
            _logger = logger;
            _settings = settings.Value;
        }

        public async Task Run()
        {
            try
            {
                _logger.LogInformation($"This is a console application for {_settings.Name}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
            }
        }
    }
}

Upvotes: 24

Views: 23671

Answers (2)

Marco
Marco

Reputation: 23945

Building upon Kirk Larkins answer (make sure you have the nuget packages installed, Microsoft.Extensions.Options.ConfigurationExtensions, Microsoft.Extensions.Logging.Console and Microsoft.Extensions.Logging.Debug) then you can simplify the logging configuration and skip the declaration of the loggerFactory by passing in an ILoggerBuilder to .AddLogging():

public static IServiceProvider ConfigureServices(IServiceCollection serviceCollection)
{
    //ILoggerFactory loggerFactory = new LoggerFactory()
    //  .AddConsole()
    //  .AddDebug();

    serviceCollection
        .AddLogging(opt =>
        {
            opt.AddConsole();
            opt.AddDebug();
        })
        .AddTransient<IFooService, FooService>();

    /*... rest of config */

    var serviceProvider = serviceCollection.BuildServiceProvider();
    return serviceProvider;
}

Upvotes: 19

Kirk Larkin
Kirk Larkin

Reputation: 93303

It looks you might be missing a couple of dependencies:

  1. Microsoft.Extensions.Logging.Console, which provides the AddConsole extension method.
  2. Microsoft.Extensions.Options.ConfigurationExtensions, which provides the Configure<T> extension method you appear to be missing.

In terms of configuring the services in .NET Core executables, Andrew Lock has a post on the topic for the first version of .NET Core. Some of this may be out of date now with .NET Core 2's recent arrival, but it's worth a read.

Upvotes: 25

Related Questions