我正在使用.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任务中?
答案 0 :(得分:0)
您可以为其创建一个类,然后将值读入该类。也可以将其更改为JSON中的列表。我会做的步骤:
将“ 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"
}
]
}
创建一个C#类,以定义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; }
}
更改配置中的数据检索:
IConfiguration configuration = BuildConfiguration(environmentName);
CosmosClient cosmosClient = BuildCosmosClient(configuration);
List<EndPoint> endPoints = configuration.GetSection("EndPointAPIStrings").Get<List<EndPoint>>();
现在,所有端点都在endPoints
变量中。您可以按照自己的喜好删除属性并将其添加到JSON中,唯一需要做的就是相应地更改类。 请注意,为了获得成功的映射,您需要在JSON和C#类中使用相同的名称。
答案 1 :(得分:0)
我已经在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",