.Net 6.0 配置文件

.Net 6.0 Configuration files

正在获取一个为 VBA 应用程序提供数据的应用程序。现在尝试获取配置文件 (appsettings.json & appsettings.Development.Json)。现在它是一个 .net6.0 控制台应用程序,稍后我将它变成一个 IconTrayApp。

运行 遇到问题,主要的 Program.cs 方法得到 appsettings.json,工人得到 appssettings.Developement.json。我明白为什么 Main() 会得到 none 环境 json,因为我明确加载了它。但我希望应用程序在 IDE.

中使用相同的文件

这里是program.cs

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PostDataService.InterfaceModels;
using Serilog;
using Serilog.Events;
using System;

namespace PostDataService
{
  public class Program
  {
    public static void Main(string[] args)
    {

      var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
      IConfiguration config = builder.Build();
      string _logFQN = config["PostConfig:Basefolder"] + config["PostConfig:LogsFolder"] + config["PostConfig:LogFname"];
      string _LogTemplate = config["PostConfig:LogTemplate"];

      var loggerConfig = new LoggerConfiguration()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Verbose)
        .Enrich.FromLogContext()
        .Enrich.WithThreadId()
        .Enrich.WithEnvironmentUserName()
        .WriteTo.File(_logFQN,
        fileSizeLimitBytes: 524288000,
        rollOnFileSizeLimit: true,
        rollingInterval: RollingInterval.Day,
        outputTemplate: _LogTemplate);

      Log.Logger = loggerConfig.CreateLogger();
      try
      {
        Log.Write(LogEventLevel.Information, "Start USPS Data Server");
        CreateHostBuilder(args).Build().Run();
      }
      catch (Exception ex)
      {
        Log.Fatal(ex, "Host terminated unexpectedly");
      }
      finally
      {
        Log.Information("USPS Server stopped");
        Log.CloseAndFlush();
      }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog()
            .ConfigureServices((hostContext, services) =>
            {
              IConfiguration configuration = hostContext.Configuration;
              WorkerOptions options = configuration.GetSection("PostConfig").Get<WorkerOptions>();
              services.AddSingleton(options);
              services.AddHostedService<Worker>();
            });

  }
}

这里是 appsettings.json (appsettings.Development.json)

{
  "PostConfig": {
    "BaseFolder": "./App_Data/",
    "LogsFolder": "logs/",
    "SystemFQN": "C:/Test/PostalDB/PostalData.db",
    "CustFQN": "C:/Test/PostalDB/PostalCustomer.db",
    "LogFname": "USPS_.log",
    "LogTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff}\t{EnvironmentUserName}\t[{Level:u4}]\t<{ThreadId}>\t{Message:lj}{NewLine}{Exception}"
  }
}

我确实尝试在配置生成器中使用 .AddEnvironmentVariables(),但似乎没有任何改变。我怀疑是因为显式的 addjsonfile 调用。

您的主应用程序(主要应用程序 - 1st)使用任何 appsettings.json 并且您需要在被调用的控制台应用程序(辅助应用程序 - 2nd)。

您可以使用参数

调用第二个

1.来自主要程序的设置文件
例如位于“C:\appsettings.json”

{
  "AppName": "Value from main/primary/1st program AppSettings.json"
}

2。来自主程序的调用
您可以使用参数 SettingsFile

发送任何文件名

dotnet .\CommandLineArgs.dll --SettingsFile=C:\appsettings.json

.\CommandLineArgs.exe --SettingsFile=C:\appsettings.json

3。副节目代码

public class Program
{
    public static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .AddJsonFile(args.Where(a => a.Contains("SettingsFile")).First().Split("=")[1], optional: false, reloadOnChange: true);
        IConfiguration config = builder.Build();
        Console.WriteLine(config.GetValue<string>("AppName"));
        Console.ReadLine();
    }
}

输出
模拟那个 powershell 是主要程序。 Primary 将值为 C:\appsettings.json 的 arg SettingsFile 发送到 中学。 辅助程序将 json 文件名添加到配置生成器并构建配置对象。

参考资料

Main() and command-line arguments
Command-line arguments

██████████████████ ██████████████████

Another implementation. You can check the code on https://github.com/JomaWhosebugAnswers/CommandLineArgs

主要应用代码
主应用程序目录必须包含辅助应用程序的可执行文件。主要应用程序使用带有设置文件名的参数启动次要应用程序。

using System.Diagnostics;

public class Program
{
    public async static Task Main(string[] args)
    {
        Console.WriteLine("██ PrimaryApp Started");
        var secondaryAppExeFilename = Path.GetFullPath("SecondaryApp/SecondaryApp.exe");
        var settingsFilename = Path.GetFullPath("appsettings.json"); // var settingsFilename = Path.GetFullPath("C:\appsettings.json");
        ProcessStartInfo info = new ProcessStartInfo();
        info.FileName = secondaryAppExeFilename;
        info.Arguments = $"--SettingsFile={settingsFilename}";
        info.WindowStyle = ProcessWindowStyle.Normal;
        Process process = new Process();
        process.StartInfo = info;
        process.Start();
        await process.WaitForExitAsync();
        Console.ReadLine();
        Console.WriteLine("█ PrimaryApp Exited");
    }
}

SecondaryAppCode
辅助应用程序从命令行参数捕获 SettingsFilename 参数并使用此文件构建配置。

using Microsoft.Extensions.Configuration;

public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("██ SecondaryApp Started");
        string settingsFile = args.Where(a => a.Contains("SettingsFile")).First().Split("=")[1];
        var builder = new ConfigurationBuilder()
            .AddJsonFile(settingsFile, optional: false, reloadOnChange: true);
        IConfiguration config = builder.Build();
        Console.WriteLine($"SettingsFile: {settingsFile}");
        Console.WriteLine($"AppName value: {config.GetValue<string>("AppName")}");
        Console.ReadLine();
        Console.WriteLine("█SecondaryApp Exited");
    }
}

appsettings.json

{
  "AppName": "PrimaryApp"
}

输出

我可能有点不清楚,Worker 得到的 appsettings.Development.json 文件是正确的,因为我在 VS 中 运行ning。我正在寻找的是一种在 Main() 方法中获得相同行为的干净方法。

我接受了 Guru Stron 的评论并强制其包含 appsettings.dev... 文件,如下所示:

      var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environments.Development}.json", optional: true, reloadOnChange: true);

它似乎工作正常,只是感觉我正在硬编码一些应该烘焙的东西。

此外,如果我 运行 来自 Windows 文件资源管理器的应用程序,我会得到 appsettings.developement.json 主要值,但 appsettings.json在工人 class 中。这是有道理的,因为文件 appsettings.development.json 会根据构建器调用覆盖 appsettings.json。不理想。