我有2个.NET Core 2.0控制台应用程序。第一个应用程序通过system.diarostics.process.start((调用第二个应用程序。以某种方式,第二个应用程序继承了位于AppSettings.development.json中的开发配置信息。
我通过在项目的根部运行 dotnet Run 来执行第一个应用程序,或在DLL存在的文件夹中运行 dotnet firstApp.dll 。这是从PowerShell开始的。
两个应用程序都是单独的目录。我不确定这是怎么发生的。
用代码
更新这些应用位于
中C:ProjectsParentConsoleApp
C:ProjectsChildConsoleApp
这是我从父级应用程序调用应用程序的方式:
System.Diagnostics.Process.Start("dotnet", "C:\projects\ChildConsoleApp\bin\Debug\netcoreapp2.0\publish\ChildConsoleApp.dll" + $" -dt {DateTime.Now.Date.ToString("yyyy-MM-dd")}");
这就是我从JSON加载配置的方式(这两个应用程序都相同(:
class Program
{
private static ILogger<Program> _logger;
public static IConfigurationRoot _configuration;
public static IServiceProvider Container { get; private set; }
static void Main(string[] args)
{
RegisterServices();
_logger = Container.GetRequiredService<ILogger<Program>>();
_logger.LogInformation("Starting GICMON Count Scheduler Service");
Configure();
// At this point DBContext has value from parent! :(
var repo = Container.GetService<ICountRepository>();
var results = repo.Count(_configuration.GetConnectionString("DBContext"), args[0]);
}
private static void Configure()
{
string envvar = "DOTNET_ENVIRONMENT";
string env = Environment.GetEnvironmentVariable(envvar);
if (String.IsNullOrWhiteSpace(env))
throw new ArgumentNullException("DOTNET_ENVIRONMENT", "Environment variable not found.");
_logger.LogInformation($"DOTNET_ENVIRONMENT environment variable value is: {env}.");
var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
if (!String.IsNullOrWhiteSpace(env)) // environment == "Development"
{
builder.AddJsonFile($"appsettings.{env}.json", optional: true);
}
_configuration = builder.Build();
}
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging((builder) => builder.SetMinimumLevel(LogLevel.Trace));
var serviceProvider = services.BuildServiceProvider();
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
loggerFactory.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true });
loggerFactory.ConfigureNLog("nlog.config");
Container = serviceProvider;
}
}
问题是由于您将配置构建器设置为当前工作目录的基本路径引起的:
var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
创建子进程时,它会从父进程继承当前目录(除非您明确设置当前目录(。
因此,儿童过程基本上使用父进程目录中的JSON配置。
有几个可能的修复:
不要将基本路径设置为当前目录。
启动应用程序时,您不确定当前目录是否匹配放置应用程序二进制文件的目录。如果您在
c:testSomeApp.exe
中有一个EXE文件,并在当前目录为c:
时从命令行启动它,则应用程序的当前目录将为c:
。在这种情况下,如果将配置构建器的基本路径设置为当前目录,则将无法加载配置文件。默认情况下,配置构建器从
AppContext.BaseDirectory
加载配置文件,这是放置应用程序二进制文件的目录。在大多数情况下,应该是理想的行为。所以只需删除
SetBasePath()
调用:var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
如果由于某种原因您要将配置构建器的基本路径设置为当前目录,则应为启动的子进程设置正确的当前目录:
var childDllPath = "C:\projects\ChildConsoleApp\bin\Debug\netcoreapp2.0\publish\ChildConsoleApp.dll"; var startInfo = new ProcessStartInfo("dotnet", childDllPath + $" -dt {DateTime.Now.Date.ToString("yyyy-MM-dd")}") { WorkingDirectory = Path.GetDirectoryName(childDllPath), }; Process.Start(startInfo);
正如@codefuller所解释的那样,原因是两个应用程序都读取相同的appsettings.{env}.json
文件。为简单起见,您可以为第二个应用程序重命名Config File(和.AddJsonFile
中的相应名称(,以防止任何可能的替代。
请参阅,当您将JSON文件注册为.AddJsonFile
的配置源时,配置API允许您使用所需的任何文件名,并且您没有被迫在这两个应用程序中使用相同的$"appsettings.{env}.json"
模式。