我有一个 .NET 6 控制台应用程序,它在多个服务器上运行以监视它们上的应用程序。
多个服务器已经为使用这些值的其他应用程序设置了环境变量。
例如:
Server A -> DOTNET_ENVIRONMENT = dev
Server B -> DOTNET_ENVIRONMENT = qa
Server C -> DOTNET_ENVIRONMENT = prod
Server D -> DOTNET_ENVIRONMENT = prod
尽管服务器 C 和 D 都是 prod 服务器,但它们需要不同的
appsettings
,因为它们监控这些服务器中的不同应用程序。因此,在服务器 C 和 D 中使用一个 appsettings.prod.json
在这种情况下不起作用。
我也不想弄乱
DOTNET_ENVIRONMENT
的值,因为该服务器上运行的其他应用程序正在使用它。
到目前为止我做了什么
我根据服务器名称命名了控制台应用程序的
appsettings.json
文件。
例如:
添加了
launchsettings
配置文件以将计算机名称作为环境变量传递(用于我的测试):
{
"profiles": {
"AppStatusWatchDog (ServerA)": {
"commandName": "Project",
"environmentVariables": {
"MachineName": "ServerA"
},
"dotnetRunMessages": "true"
}
}
}
并尝试在启动过程中加载正确的
appsettings.json
:
public static void Main(string[] args)
{
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
// Just calling Environment.MachineName is adequate here. GetEnvironmentVariable("MachineName") is here because we supply MachineName's value during local testing using launch profile.
var machineName = Environment.GetEnvironmentVariable("MachineName") ?? Environment.MachineName;
var config = new ConfigurationBuilder()
.SetBasePath(pathToContentRoot)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{machineName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
// Rest of the code here...
}
这里
config
加载了我拥有的所有设置,即appsettings.json
,appsettings.ServerA.json
和环境变量,这很好🙌。
当我尝试通过将
IConfiguration
注入某个类的构造函数来使用配置时,问题就出现了😧,此时它会加载 appsettings.json
和环境变量,但不会加载 appsettings.ServerA.json
。
我在这里做错了什么?
您应该按如下方式修改启动设置:
{
"profiles": {
"AppStatusWatchDog (ServerA)": {
"commandName": "Project",
"commandLineArgs": "--MachineName=ServerA",
"dotnetRunMessages": "true"
}
}
}
接下来,您需要修改 Main 方法以正确解析命令行参数:
public static void Main(string[] args)
{
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
// Parse command line arguments to find the machine name
var machineName = "default"; // Default value if no argument is provided
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "--MachineName" && i + 1 < args.Length)
{
machineName = args[i + 1];
break;
}
}
var config = new ConfigurationBuilder()
.SetBasePath(pathToContentRoot)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{machineName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
// Rest of the code here...
}
请告诉我这是否可以解决您的问题。
appsettings.X.json
配置文件根据控制台应用程序中 IConfiguration
变量的值加载到 DOTNET_ENVIRONMENT
中。 (ASPNETCORE_ENVIRONMENT
适用于网络应用程序。更多信息此处)。
试试这个:
public static void Main(string[] args)
{
var machineName = Environment.GetEnvironmentVariable("MachineName") ?? Environment.MachineName;
// IMPORTANT part: 👇
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", machineName);
// For machine level change (Don't do this here):
// Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", machineName, EnvironmentVariableTarget.Machine); // Reference: https://stackoverflow.com/a/19705691/8644294
// If you're going to use config through dependency injection, you don't even
// need to build 'config' below and this line can be removed altogether.
// (Example of using config using dependency injection is shown below).
// But for whatever reason you need 'config' in your 'Rest of the code here...'
// part, keep this as is:
var config = new ConfigurationBuilder()
//.SetBasePath(Directory.GetCurrentDirectory()) // Not really needed though. Uncomment it if you'd like.
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{machineName}.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
// Rest of the code here...
}
像这样使用它:
public class SomeClass
{
private readonly IConfiguration _config;
public SomeClass(IConfiguration config)
{
_config = config; // 👈 This will have settings from appsettings.json, appsettings.ServerA.json, environment variables of the machine it's running on and so on.
}
}
注意:
appsettings.json
的属性应如下所示: