Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core / Console Application / Configuration / XML

My first little venture into the .Net Core libraries using the new ConfigurationBuilder, and Options pattern.

Lot's of good examples here: https://docs.asp.net/en/latest/fundamentals/configuration.html and a good copy of the example here

Item 1. it says this can be used with non MVC applications, but no examples on how to use it without MVC - particularly if you are using a custom, strongly-typed class. I would like to see an example of showing the setup of DependencyInjection, Configuration, and Logging using a Console application.

Item 2. it says you can write back, but no examples or documentation as to how to persist any changes back to the file store. I would like to see an example of how persist changes back into the configuration using a strongly typed class. In both Json or XML?

Item 3. all examples require a hand bombed initial file - would like to see an example where the initial json/xml file is created from a strongly-typed class (comes in handy when there are many parameters for the application).

If I can spend enough time on this (rather than re-post an example already in the documentation) I'll do it! If you know of a post/documentation that will help me, I would appreciate it.

like image 507
codeputer Avatar asked Aug 01 '16 19:08

codeputer


People also ask

How do I add a config file to a .NET Core console application?

In a . NET core console application Configuration can be added using the ConfigurationBuilder class. Additionally, support for configuring the application using a Json file, environmental variables, command line or using a custom configuration provider can also be added.

Can you use app config in .NET Core?

Application configuration in ASP.NET Core is performed using one or more configuration providers. Configuration providers read configuration data from key-value pairs using a variety of configuration sources: Settings files, such as appsettings. json.

Where is app config file in C#?

In Solution Explorer, right-click the project node, and then select Add > New Item. The Add New Item dialog box appears. Expand Installed > Visual C# Items. In the middle pane, select the Application Configuration File template.


1 Answers

How do I configure a .NET Core 1.0.0 Console Application for Dependency Injection, Logging and Configuration?

A lot of what was written is deprecated after RC2. (see issue). Fortunatelly there are some updated posts with excelent info:

Essential .NET - Dependency Injection with .NET Core

Essential .NET - Logging with .NET Core

I came up with the following solution. I bet there are things that can be improved, please leave comments so I can improve this answer.

In my static void Main, I

  • Setup Dependency injection
  • Invoke ConfigureServices
  • Instantiate my Application class using DI
  • Switch from 'sync Main' to 'async Application.Run()' (It makes sense to me to switch to async as soon as possible and only once.)

On my Application Class:

  • I inject as much as possible on the class constructor.
  • Catch any exception on the Run() method.

Here is the code.

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Configuration;
using System.IO;

public class Program
{
    static void Main(string[] args)
    {
        IServiceCollection serviceCollection = new ServiceCollection();

        ConfigureServices(serviceCollection);

        // Application application = new Application(serviceCollection);
        IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

        var app = serviceProvider.GetService<Application>();

        // For async
        Task.Run(() => app.Run()).Wait(); // Exceptions thrown here will be lost! Catch them all at Run()
        // Otherwise use sync as in: app.Run();            
    }

    private static void ConfigureServices(IServiceCollection services)
    {
        ILoggerFactory loggerFactory = new LoggerFactory()
            .AddConsole()
            .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"));  

        services.AddTransient<Application>();
    }

    private static IConfigurationRoot GetConfiguration()
    {
        return new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile($"appsettings.json", 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());
        }
    }
}
}

The AppSettings.json file:

{
  "MyOptions": {
    "Name" : "John"
  }
}

And the project.json file:

 "dependencies": {
    "Microsoft.Extensions.Configuration": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.DependencyInjection": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options": "1.0.0",
    "Microsoft.Extensions.PlatformAbstractions": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",

On your question #2: I've read the document and unless I am missing something, it does not says you can write configuration. I'm not sure you can do that, unless you edit the JSON files manually using Newtonsoft.JSON.

If a name/value pair is written to Configuration, it is not persisted. This means that the written value will be lost when the sources are read again.

For your question #3 I've included a default AppSettings.json file. Your config should have a Section where its settings match by name to the public properties of your settings class.

like image 167
Gerardo Grignoli Avatar answered Sep 30 '22 13:09

Gerardo Grignoli