89 votes

Application console .NET Core, comment configurer appSettings par environnement ?

J'ai une application console .NET Core 1.0.0 et deux environnements. Je dois être en mesure d'utiliser appSettings.dev.json et appSettings.test.json en fonction des variables d'environnement que je définis au moment de l'exécution. Cela semble assez simple pour les applications web ASP.NET Core, grâce à l'injection de dépendances, à IHostingEnvironment et à la variable d'environnement EnvironmentName, mais comment dois-je organiser les choses pour l'application console (à part écrire mon propre code personnalisé qui utilise Microsoft.Framework.Configuration.EnvironmentVariables ) ?

Merci.

113voto

Jaya Points 1806

C'est ainsi que nous procédons dans notre .netcore l'application de la console. La clé ici est d'inclure le bon Dépendances sur votre projet à savoir ( peut-être pas tous, vérifiez en fonction de vos besoins ) et copie à la sortie l'appSetting.json en tant que partie de votre options de construction

  {
    "buildOptions": {
    "emitEntryPoint": true,
    "copyToOutput": {
       "include": [
       "appsettings*.json",
       "App*.config"
                 ]
          }
},

using Microsoft.Extensions.Configuration;
namespace MyApp
{
    public static void Main(string[] args)
    {
        var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        var builder = new ConfigurationBuilder()
            .AddJsonFile($"appsettings.json", true, true)
            .AddJsonFile($"appsettings.{environmentName}.json", true, true)
            .AddEnvironmentVariables();
        var configuration = builder.Build();
        var myConnString= configuration.GetConnectionString("SQLConn");
    }
}

4 votes

Merci. J'ai fini par utiliser une version plus alambiquée de cette méthode, en utilisant new ConfigurationBuilder().AddEnvironmentVariables() et trouver ASPNETCORE_ENVIRONMENT .

0 votes

Je ne trouve pas d'options de construction dans l'application console.

2 votes

Je pense que vous devriez ajouter un nuget Microsoft.Extensions.Configuration.Json paquet nuget : docs.microsoft.com/fr/aspnet/core/fundamentals/configuration/

24voto

user680032 Points 11

Pour ceux qui utilisent .NET Core version 2.1.0+ et Microsoft.Extensions.Hosting pour héberger leur application de console, vous pouvez utiliser le code suivant (selon l'article de Feiyu Zhou) réponse dans un autre fil) :

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

10voto

MovGP0 Points 77

Il y a deux IHostingEnvironment interfaces que vous devriez utiliser. L'une est destinée aux applications ASP.NET Core, l'autre aux applications .NET Core Console. Vous pouvez utiliser cet exemple de code pour les deux :

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") ?? "Production",
                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();
        }
    }
}

1 votes

Console App "version" namespace "Microsoft.Extensions.Hosting" , interface "IHostingEnvironment" , fichier d'assemblage : "microsoft.extensions.hosting.abstractions \2.1.1\lib\netstan dard2.0 \Microsoft.Ex tensions.Hosting.Abstractions.dll" (en anglais)

1 votes

Voici la liste des paquets nuget que j'ai dû ajouter pour que ce code fonctionne. <PackageReference I="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.1.1" /> <PackageReference I="Microsoft.Extensions.Configuration" Version="2.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2. 1.1" /> <PackageReference I="Microsoft.Extensions.Configuration.Json" Version="2.1.1" /> <PackageReference I="Microsoft.Extensions.Hosting" Version="2.1.1" /> <PackageReference I="Microsoft.Extensions.Hosting.Abstractions" Version="2.1.1" />

0 votes

Dois-je créer une dépendance de l'espace de nom Microsoft.AspNetCore dans un projet d'application console ?

4voto

chaosifier Points 452

Si comme moi, vous essayez simplement d'avoir un fichier de configuration différent pour le mode Release et le mode Development, il suffit d'ajouter un fichier appsettings.Development.json avec le paramètre CopyToOutputDirectory défini à true dans la fenêtre de propriétés du fichier.

Maintenant, pour accéder au fichier en fonction de la configuration de la construction, vous pouvez utiliser le #if DEBUG directive du préprocesseur .

Voici un exemple :

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
}

3 votes

C'est une mauvaise solution car elle peut cacher des erreurs de compilation, qui deviennent alors apparentes une fois que vous poussez vers un serveur de construction et que la directive devient vraie/faux. Il est bien mieux d'utiliser une variable d'environnement. Je ne juge pas pour autant - j'ai fait cela dans le passé de nombreuses fois, c'est juste que j'ai rencontré le problème que j'ai mentionné à plusieurs reprises.

0 votes

Je vous recommande toujours ajouter le appsettings.json (ce qui résout le problème de @jcvandan, qui ne le charge jamais) et le fichier #if DEBUG également charger le appsettings.Development.json - la méthode standard consiste à permettre au développement de passer outre les paramètres si nécessaire, sans avoir à les spécifier tous.

4voto

Steve Rakebrandt Points 139

Ces mesures environnementales semblent convenir à la plupart des gens, mais je ne suis pas du tout d'accord avec toute cette gestion de l'environnement. Ni le runtime ni le système cible ne savent ce qu'il est. Seul vous, en tant que développeur ou mécanisme de déploiement, savez ce qu'est le système cible.

Tout le monde parle de la variable ASPNETCORE_ENVIRONMENT, même la documentation officielle comme ici https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-3.0 . Mais en fait, quelqu'un doit définir explicitement un système comme système de production, par exemple en définissant une fois manuellement ASPNETCORE_ENVIRONMENT. Voulez-vous vraiment supposer et vous fier au fait que ce paramètre est déjà défini dans chaque environnement que vous utilisez ? Non, vous ne pouvez pas. Que se passe-t-il si vous devez déployer une application console sur un serveur batch où aucun site Web n'est en cours d'exécution ? ASPNETCORE_ENVIRONMENT n'est pas disponible. Que faire si vous devez déployer et exécuter un webapi .net core sans IIS, uniquement avec Kestrel ? Pas de web.config et pas de variable d'environnement. Voulez-vous que votre équipe d'administration/opération définisse cette variable trompeuse pour votre application console ? Dans ce contexte, j'ai vu beaucoup de projets qui ont des paramètres d'application comme celui-ci par projet :

appsettings.json
appsettings.development.json
appsettings.test.json
appsettings.uat.json
appsettings.staging.json
appsettings.production.json

Gardez à l'esprit que par défaut, chacun de ces fichiers sera publié et également déployé sur le système cible. À première vue, il semble très facile de laisser l'environnement "décider" de la configuration à utiliser. Mais vous avez une configuration et aussi des informations d'identification potentiellement déployées sur un système qui n'est pas prévu pour cela.

Conclusion

Je recommande appsettings.json + appsettings.release.json. Le premier est seulement pour dev. Changez-le, jouez avec comme vous voulez. Le dernier est une configuration VALIDE prête pour le déploiement (processus). Avant que le déploiement ne commence, transformez la configuration pour qu'elle soit prête pour le système cible. C'est tout. Plus besoin de compter sur les paramètres de la machine cible, plus de configurations désordonnées. Gardez le contrôle total de votre application, même lorsque les serveurs changent rapidement (comme la mise à l'échelle en général, les VM, le cloud, etc.)

J'apprécie les commentaires constructifs :-)

1 votes

Vous passez un peu à côté de l'essentiel et oui, la condition pourrait être déterminée par une valeur de configuration au lieu d'une variable d'environnement. J'ai un comportement d'application différent dans les API Web où j'utilise swagger pour que les développeurs puissent examiner et tester les points de terminaison. Comme j'ai un processus cohérent de gestion des versions qui consiste à promouvoir les mêmes binaires dans un environnement de production, cette fonction doit être activée. Que cela soit réalisé par un paramètre de configuration par application/environnement ou par une variable d'environnement unique n'est pas pertinent, sauf que les paramètres d'environnement s'appliquent à toutes les applications sur le même serveur, contrairement aux configurations des applications.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X