简体   繁体   中英

.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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM