从appsettings.json向.net核心控制台应用程序添加多个终结点路由

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从appsettings.json向.net核心控制台应用程序添加多个终结点路由相关的知识,希望对你有一定的参考价值。

我正在使用.net core 3.1来构建充当事件处理程序API的控制台应用程序。

该应用程序捕获对数据库的更改,并将这些更改实时定向到其他API。对“客户”的更新转到“ customerAPI”,“产品”转到“ productAPI”,依此类推。这意味着我有一个如下的appsettings.Local.json:

 "DBConnectionStrings": {
    "DefaultConnection": "AccountEndpoint=(my account)",
    "SourceDatabaseName": "MyDB",
    "SourceContainerName": "MySource",
    "LeasesContainerName": "MyLease",
    "PartitionKey": "/id"
  },
  "EndpointAPIStrings": {
    "Endpoint1": {
      "EndpointUrl": "https://localhost:7777",
      "Username": "myusername1",
      "Password": "mypassword1",
    "Endpoint2": {
      "EndpointUrl": "https://localhost:8888",
      "Username": "myusername2",
      "Password": "mypassword2",
    "Endpoint3": {
      "EndpointUrl": "https://localhost:9999",
      "Username": "myusername3",
      "Password": "mypassword3"
    ...
    }

我目前正在使用一种app脚的方法将其声明为EnvironmentVariables,以从我的Main那里获取它们,在Main中将其配置构建到我的CallAPI Task。

主要:

public static async Task Main(string[] args)
{
    ...
    IConfiguration configuration = BuildConfiguration(environmentName);
    CosmosClient cosmosClient = BuildCosmosClient(configuration);

    Environment.SetEnvironmentVariable("EndpointUrl", configuration["EndpointAPIStrings:Endpoint1:EndpointURL"]);
    Environment.SetEnvironmentVariable("Username", configuration["EndpointAPIStrings:Endpoint1:Username"]);
    Environment.SetEnvironmentVariable("Password", configuration["EndpointAPIStrings:Endpoint1:Password"]);
    ...
}

代理功能:

...
if (entityType == "myproduct")
{
    var entity = "products";
    var result = await Task.Run(() => CallAPIAsync(entity, item));
}
...

任务CallAPI:

public static async Task<HttpResponseMessage> CallAPIAsync(string entity, ProcessedItem item)
{
    using (var client = new HttpClient())
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        var endpointUrl = Environment.GetEnvironmentVariable("EndpointUrl");
        var uri = new Uri($"{endpointUrl}/api/{entity}/{item.Id}/propagate");
        string username = Environment.GetEnvironmentVariable("Username");
        string password = Environment.GetEnvironmentVariable("Password");
        ...
    }
}

这显然仅适用于第一个端点,而忽略其他端点。

我该如何重构它以将所有EndpointAPIString的值获取到我的CallAPI任务中?

答案

您可以为其创建一个类,然后将值读入该类。也可以将其更改为JSON中的列表会很好。我会做的步骤:

  1. 将'EndpointAPIStrings'更改为数组:

    {
      "EndpointAPIStrings":[
        {
           "Id":"Endpoint1",
           "EndpointUrl":"https://localhost:7777",
           "Username":"myusername1",
           "Password":"mypassword1"
        },
        {
           "Id":"Endpoint2",
           "EndpointUrl":"https://localhost:8888",
           "Username":"myusername2",
           "Password":"mypassword2"
        },
        {
           "Id":"Endpoint3",
           "EndpointUrl":"https://localhost:9999",
           "Username":"myusername3",
           "Password":"mypassword3"
        }
      ]
    }
    
  2. 创建一个定义JSON数组中对象的C#类:

    public sealed class EndPoint {
        public string Id { get; set; }
    
        public string EndPointUrl { get; set; }
    
        public string Username { get; set; }
    
        public string Password { get; set; }
    }
    
  3. 从配置中更改数据检索:

    IConfiguration configuration = BuildConfiguration(environmentName);
    CosmosClient cosmosClient = BuildCosmosClient(configuration);
    
    List<EndPoint> endPoints = configuration.GetSection("EndPointAPIStrings").Get<List<EndPoint>>();
    

现在,所有端点都在endPoints变量中。您可以按照自己的喜好删除属性并将其添加到JSON中,唯一需要做的就是相应地更改类。 请注意,为了获得成功的映射,您需要在JSON和C#类中使用相同的名称。

另一答案

我已经在Windows Service .net Core 3.1应用程序中完成了此操作,非常相似。本质上,当您在program.cs中调用IHostBuilder函数时]

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureLogging(loggerFactory => loggerFactory.AddEventLog())
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });

默认情况下,您可以从appsettings.json访问配置变量。然后可以在您的主要启动或执行功能中进行访问:

private readonly ILogger<Worker> _logger;

private readonly IServiceScopeFactory _serviceScopeFactory;

private readonly IConfiguration _config;

public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory, IConfiguration config)
            {
                _logger = logger;
                _serviceScopeFactory = serviceScopeFactory;
                _config = config;
            }  

然后在您的main或execute函数中:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // Must be a scoped process in order to run correctly
            using var scope = _serviceScopeFactory.CreateScope();
            // Start timer and begin log
            var startTime = DateTime.UtcNow;
            var env = _config.GetValue<string>("ENV");
            var stageTable = _config.GetValue<string>("StageTable");
            var prevTable = _config.GetValue<string>("PrevTable");
            var mainTable = _config.GetValue<string>("MainTable");
            var sqlConnectionString = _config.GetValue<string>("SqlConnString_" + env);
            var excelConnectionString = _config.GetValue<string>("ExcelConnectionString1") +
                                        _config.GetValue<string>("ExcelFilePath_" + env) +
                                        _config.GetValue<string>("ExcelFileName") +
                                        _config.GetValue<string>("ExcelConnectionString2");

带有一个appsettings.json,如:

"ENV": "LOCAL",
"StageTable": "Staging",
"PrevTable": "Previous",
"MainTable": "Courses",

以上是关于从appsettings.json向.net核心控制台应用程序添加多个终结点路由的主要内容,如果未能解决你的问题,请参考以下文章

。net核心Web作业中如何从appsettings.json中读取Cron表达式

json Asp.net核心访问appsettings.json

ConfigurationManager 是不是与 ASP.NET 核心的 appsettings.json 一起使用?

为asp.net核心中的开发和发布环境自动设置appsettings.json?

现在可以在从 Windows 任务调度程序运行 .net 核心控制台应用程序时读取 appsettings.json 文件中存在的连接字符串

带有列表的 asp.net 核心 ioptions