簡體   English   中英

從 appsettings.json 將多個端點路由添加到 .net 核心控制台應用程序

[英]Adding multiple endpoint routes to .net core console app from appsettings.json

我正在使用 .net 核心 3.1 來構建一個控制台應用程序,該應用程序充當事件處理程序 API。

該應用程序實時捕獲對數據庫的更改並將這些更改定向到其他 API。 將“customer”go 更新為“customerAPI”,“product”更新為“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"
    ...
    }

我目前正在使用一種糟糕的方法將它們聲明為 EnvironmentVariables 以從我的 Main 中獲取它們,在該 Main 中將配置構建到我的 CallAPI 任務中。

主要的:

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"]);
    ...
}

代表 function:

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

任務調用API:

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");
        ...
    }
}

這顯然只適用於第一個端點,而忽略其他端點。

如何重構它以將所有 EndpointAPIStrings 的值放入我的 CallAPI 任務中?

您可以為其創建一個 class 並將值讀入該 class。 也將其更改為 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. 創建一個 C# class 定義 JSON 數組中的對象:

     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 中,您唯一需要做的就是相應地更改 class。 請注意,您需要在 JSON 和 C# class 中使用相同的名稱才能成功映射。

我在 Windows 服務 .net Core 3.1 應用程序中完成了此操作,非常相似。 本質上,當您在 program.cs 中調用 IHostBuilder function

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

默認情況下,您可以從 appsettings.json 訪問配置變量。 然后可以在您的主啟動中訪問或執行 function:

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

然后在你的主要或執行function:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM