Ich habe eine .NET Core 1.0.0-Konsolenanwendung und zwei Umgebungen. Ich muss den Einsatz in der Lage sein appSettings.dev.json
und appSettings.test.json
basiert auf Umgebungsvariablen ich zur Laufzeit festgelegt. Dies scheint für ASP.NET Core-Webanwendungen über die Abhängigkeitsinjektion und IHostingEnvironment sowie die EnvironmentName-Umgebung recht einfach zu sein. Variable, aber wie soll ich die Dinge für die Konsolenanwendung verkabeln (außer meinen eigenen benutzerdefinierten Code zu schreiben, der verwendet Microsoft.Framework.Configuration.EnvironmentVariables
)?
Vielen Dank.
quelle
new ConfigurationBuilder().AddEnvironmentVariables()
und gefundenASPNETCORE_ENVIRONMENT
.Microsoft.Extensions.Configuration.Json
Nuget-Paket hinzufügen : docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/…Für diejenigen, die .NET Core Version 2.1.0+ und Microsoft.Extensions.Hosting zum Hosten Ihrer Konsolen-App verwenden, können Sie den folgenden Code verwenden (gemäß der Antwort von Feiyu Zhou in einem anderen Thread):
var hostBuilder = new HostBuilder() .ConfigureHostConfiguration(config => { if (args != null) { // enviroment from command line // e.g.: dotnet run --environment "Staging" config.AddCommandLine(args); } }) .ConfigureAppConfiguration((context, builder) => { builder.SetBasePath(AppContext.BaseDirectory) .AddJsonFile("appsettings.json", optional: false) .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true); })
quelle
Es gibt zwei
IHostingEnvironment
Schnittstellen, die Sie verwenden sollten. Eine ist für ASP.NET Core-Anwendungen, die andere für .NET Core Console-Anwendungen. Sie können dieses Codebeispiel für beide verwenden:using System; using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting.Internal; namespace MyApplication.Common { public static class ConfigurationFactory { /// <summary> /// Use for ASP.NET Core Web applications. /// </summary> /// <param name="config"></param> /// <param name="env"></param> /// <returns></returns> public static IConfigurationBuilder Configure(IConfigurationBuilder config, IHostingEnvironment env) { return Configure(config, env.EnvironmentName); } /// <summary> /// Use for .NET Core Console applications. /// </summary> /// <param name="config"></param> /// <param name="env"></param> /// <returns></returns> private static IConfigurationBuilder Configure(IConfigurationBuilder config, Microsoft.Extensions.Hosting.IHostingEnvironment env) { return Configure(config, env.EnvironmentName); } private static IConfigurationBuilder Configure(IConfigurationBuilder config, string environmentName) { return config .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); } /// <summary> /// Use for .NET Core Console applications. /// </summary> /// <returns></returns> public static IConfiguration CreateConfiguration() { var env = new HostingEnvironment { EnvironmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), ApplicationName = AppDomain.CurrentDomain.FriendlyName, ContentRootPath = AppDomain.CurrentDomain.BaseDirectory, ContentRootFileProvider = new PhysicalFileProvider(AppDomain.CurrentDomain.BaseDirectory) }; var config = new ConfigurationBuilder(); var configured = Configure(config, env); return configured.Build(); } } }
quelle
Diese Umweltsachen scheinen für die meisten Menschen zu funktionieren, aber ich bin mit all dem Umweltmanagement überhaupt nicht einverstanden. Ob die Laufzeit oder das Zielsystem weiß, was es ist. Nur Sie als Entwickler oder Bereitstellungsmechanismus kennen das Zielsystem.
Alle reden über die Variable ASPNETCORE_ENVIRONMENT, sogar über die offizielle Dokumentation wie hier https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-3.0. Tatsächlich muss jemand ein System explizit als Produktionssystem definieren, indem er beispielsweise ASPNETCORE_ENVIRONMENT einmal manuell einstellt. Möchten Sie wirklich davon ausgehen und sich darauf verlassen, dass dies bereits in jeder von Ihnen verwendeten Umgebung festgelegt ist? Nein, das kannst du nicht. Was ist, wenn Sie eine Konsolen-App auf einem Batch-Server bereitstellen müssen, auf dem keine Website ausgeführt wird? ASPNETCORE_ENVIRONMENT ist nicht verfügbar. Was ist, wenn Sie eine .net Core-Webapi ohne IIS nur mit Turmfalke bereitstellen und ausführen müssen? Keine web.config und keine Umgebungsvariable. Möchten Sie, dass Ihre Administratoren / Ihr Betriebsteam diese irreführende Variable für Ihre Konsolen-App festlegen? In diesem Zusammenhang habe ich viele Projekte gesehen, die Appsettings wie dieses pro Projekt haben:
Beachten Sie, dass standardmäßig jede dieser Dateien veröffentlicht und auch auf dem Zielsystem bereitgestellt wird. Auf den ersten Blick sieht es sehr einfach aus, die Umgebung "entscheiden" zu lassen, welche Konfiguration verwendet werden soll. Sie haben jedoch Konfiguration und möglicherweise auch Anmeldeinformationen auf einem System bereitgestellt, das nicht für dieses System vorgesehen ist.
Fazit
Ich empfehle appsettings.json + appsettings.release.json. Erstens ist nur für Entwickler. Ändere es, spiele damit, wie du willst. Die letzte ist eine GÜLTIGE Konfiguration, die für die Bereitstellung (den Prozess) bereit ist. Transformieren Sie die Konfiguration vor Beginn der Bereitstellung so, dass sie für das Zielsystem bereit ist. Das ist es. Keine Notwendigkeit, sich auf Einstellungen auf dem Zielcomputer zu verlassen, keine unordentlichen Konfigurationen. Behalten Sie die volle Kontrolle über Ihre App, auch wenn sich Server schnell ändern (z. B. Skalierung im Allgemeinen, VMs, Cloud usw.).
Ich freue mich über konstruktives Feedback :-)
quelle
Sie können dies für die Umgebungsvariable ASP.Net Core (ASPNETCORE_ENVIRONMENT) tun: -
using Microsoft.AspNetCore.Hosting; using System; public class Program { private static string HostingEnvironment => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); private static bool IsEnvironment(string environmentName) => HostingEnvironment?.ToLower() == environmentName?.ToLower() && null != environmentName; private static bool Development => IsEnvironment(EnvironmentName.Development); private static bool Production => IsEnvironment(EnvironmentName.Production); private static bool Staging => IsEnvironment(EnvironmentName.Staging); public static void Main(string[] args) { // Your code here } }
Dann können Sie einfach die Eigenschaft verwenden
public static void Main(string[] args) { if (Development){ // Blow up the planet } }
quelle
Wenn Sie wie ich einfach versuchen, eine andere Konfigurationsdatei für den Release- und Entwicklungsmodus zu erstellen, fügen Sie einfach eine Datei appsettings.Development.json hinzu, wobei die Einstellung CopyToOutputDirectory im Eigenschaftenfenster der Datei auf true festgelegt ist.
Um nun abhängig von der Build-Konfiguration auf die Datei zuzugreifen, können Sie die Präprozessor-Direktive #if DEBUG verwenden .
Hier ist ein Beispiel:
static void Main(string[] args) { #if DEBUG var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.Development.json", true, true); #else var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, true); #endif var configuration = builder.Build(); // ... use configuration }
quelle
appsettings.json
Datei hinzufügen (die das Problem von @ jcvandan behebt, sie niemals zu laden) und#if DEBUG
auch dieappsettings.Development.json
- die Standardmethode besteht darin, der Entwicklung zu erlauben, Einstellungen bei Bedarf zu überschreiben, ohne sie alle angeben zu müssen.Für eine Dotnet 2.x-Kernkonsolenanwendung ist dies ungefähr so:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; [...] var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables() .Build(); var serviceProvider = new ServiceCollection() .AddLogging(options => options.AddConfiguration(configuration).AddConsole()) .AddSingleton<IConfiguration>(configuration) .AddSingleton<SomeService>() .BuildServiceProvider(); [...] await serviceProvider.GetService<SomeService>().Start();
Das könnten Sie ILoggerFactory, IConfiguration in die injizieren
SomeService
.quelle