.NET Core / 控制台应用程序 / 配置 / XML

9

使用新的ConfigurationBuilder和Options模式,我第一次尝试了.Net Core库。

这里有很多好的例子:https://docs.asp.net/en/latest/fundamentals/configuration.html, 这里有一个良好的示例here

项目1:文中提到此功能可用于非MVC应用程序,但没有展示如何在没有MVC的情况下使用它的例子,特别是如果你使用自定义的强类型类。我想要看到一个展示如何在控制台应用程序中使用DependencyInjection、Configuration和Logging的例子。

项目2:文中说可以写回,但没有任何关于如何将更改持久化到文件存储的例子或文档。我想要看到如何使用强类型类将更改持久化到配置文件中的例子,包括Json或XML格式。

项目3:所有示例都需要手动创建初始文件。 我希望看到一个从强类型类创建初始json/xml文件的例子(当应用程序有许多参数时非常方便)。

如果我能够花足够的时间在这上面(而不是转载已经在文档中的示例),我会做到的! 如果您知道可以帮助我的文章/文档,我将不胜感激。


你说你有问题,但我没有看到任何问题,只是抱怨缺少示例。如果你在寻求这些示例,那么这不是 SO 的目的。 - svick
我找不到任何我需要的示例或文档,希望其他开发人员能指引我正确的方向,或者给我一些相关的文档。 - codeputer
微软欢迎社区在其文档网站和Stack Overflow文档中撰写此类主题。您可以关注它们或在那里提出请求。像这样快速移动的平台使得记录变得乏味,因此我并不惊讶许多东西都被遗漏了。 - Lex Li
1个回答

20

如何为依赖注入、日志记录和配置配置.NET Core 1.0.0控制台应用程序?

很多旧的内容已经在RC2之后过时了。(见问题). 幸运的是,有一些更新的文章提供了出色的信息:

Essential .NET - 使用.NET Core进行依赖注入

Essential .NET - 使用.NET Core进行日志记录

我想出了以下解决方案。我敢打赌有些可以改进的地方,请留下评论,以便我完善这个答案。

在我的static void Main中,我:

  • 设置依赖注入
  • 调用ConfigureServices
  • 使用DI实例化我的Application
  • 从同步的Main切换到'async Application.Run()' (对我来说,尽可能快地切换到异步只有一次是有意义的)

在我的Application类中:

  • 在类构造函数中尽可能注入
  • 捕获Run()方法的任何异常

以下是代码。

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());
        }
    }
}
}

AppSettings.json文件:

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

还有 project.json 文件:

 "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",

关于你的第二个问题:我已经阅读了这份文档,除非我漏看了什么,否则它并没有说你可以编写配置。我不确定除非你使用Newtonsoft.JSON手动编辑JSON文件,否则你是否能够这样做。

如果将名称/值对写入Configuration,则不会持久化该对。这意味着在再次读取源时,写入的值将丢失。

对于你的第三个问题,我已经包含了一个默认的AppSettings.json文件。你的配置应该有一个部分,其中其设置按名称与你的设置类的公共属性相匹配。


哇,我好久没见到UTF-16了...需要检查的是你的文本文件编码(在记事本中:另存为->编码)和你的<?xml version="1.0" encoding="ISO-8859-1"?>标签。建议先从用记事本或vi创建一个简单的纯文本XML文件开始(不要复制粘贴,只需打字)。一旦这个可以工作,再尝试增加XML内容。 - Gerardo Grignoli
这是XML配置还是纯数据?您也可以使用System.Xml.Linq.XDocument进行读取。 - Gerardo Grignoli
Gerardo - 根据您的博客,我通过简单地从XML顶部删除<?xml version="1.0" encoding="utf-16"?>来摆脱了错误。我通过XmlSerializXML序列化一个类来创建此XML。这个类将代表一个大型配置文件 - 一个类,带有许多属性 - 我想在启动时重新生成该类。我的理论是,如果文件不存在,则可以通过序列化具有默认值的类来创建它。 - codeputer
1
希望能够更新到 .net core 2.0 版本。 - zaitsman
我在var app = serviceProvider.GetService<Application>()处得到了空值。 - ca9163d9
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接