Configurazione ASP.NET Core per l'applicazione console .NET Core


Risposte:


76

Puoi utilizzare questo frammento di codice. Include configurazione e DI.

public class Program
{
    public static ILoggerFactory LoggerFactory;
    public static IConfigurationRoot Configuration;

    public static void Main(string[] args)
    {
        Console.OutputEncoding = Encoding.UTF8;

        string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        if (String.IsNullOrWhiteSpace(environment))
            throw new ArgumentNullException("Environment not found in ASPNETCORE_ENVIRONMENT");

        Console.WriteLine("Environment: {0}", environment);

        var services = new ServiceCollection();

        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(AppContext.BaseDirectory))
            .AddJsonFile("appsettings.json", optional: true);
        if (environment == "Development")
        {

            builder
                .AddJsonFile(
                    Path.Combine(AppContext.BaseDirectory, string.Format("..{0}..{0}..{0}", Path.DirectorySeparatorChar), $"appsettings.{environment}.json"),
                    optional: true
                );
        }
        else
        {
            builder
                .AddJsonFile($"appsettings.{environment}.json", optional: false);
        }

        Configuration = builder.Build();

        LoggerFactory = new LoggerFactory()
            .AddConsole(Configuration.GetSection("Logging"))
            .AddDebug();

        services
            .AddEntityFrameworkNpgsql()
            .AddDbContext<FmDataContext>(o => o.UseNpgsql(connectionString), ServiceLifetime.Transient);

        services.AddTransient<IPackageFileService, PackageFileServiceImpl>();

        var serviceProvider = services.BuildServiceProvider();

        var packageFileService = serviceProvider.GetRequiredService<IPackageFileService>();

        ............
    }
}

Oh, e non dimenticare di aggiungere il project.json

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true,
    "copyToOutput": {
      "includeFiles": [
        "appsettings.json",
        "appsettings.Integration.json",
        "appsettings.Production.json",
        "appsettings.Staging.json"
      ]
    }
  },

  "publishOptions": {
    "copyToOutput": [
      "appsettings.json",
      "appsettings.Integration.json",
      "appsettings.Production.json",
      "appsettings.Staging.json"
    ]
  },
...
}

12
Questa risposta non è l'ideale. Usa Directory.GetCurrentDirectory()invece di AppContext.BaseDirectory. Successivamente non dovrebbe essere necessario l'hacking.
Matyas,

1
Oppure imposta la proprietà "Copia nella directory di output" su "Copia se più recente" in Visual Studio per i file JSON.
BuddhiP,

Per dir base per il lavoro in Web, Console e WinForms è possibile utilizzare questo approccio stackoverflow.com/a/33675039/1818723
Pawel Cioch

Gary Woodfine lo ha descritto in dettaglio in un ottimo stile in questo post: garywoodfine.com/configuration-api-net-core-console-application
Javad Norouzi

@javad Solo parzialmente; Sono finito qui perché volevo la parte DI, che ha promesso ma non ho trovato. Inoltre, non ha mostrato come utilizzare più file di configurazione come nell'esempio.
Auspex,

232

Per un'app console .NET Core 2.0, ho fatto quanto segue:

  1. Crea un nuovo file chiamato appsettings.json alla radice del progetto (il nome del file può essere qualsiasi cosa)
  2. Aggiungi le mie impostazioni specifiche a quel file come json. Per esempio:
{
  "myKey1" :  "my test value 1", 
  "myKey2" :  "my test value 2", 
  "foo" :  "bar" 
}
  1. Configura per copiare il file nella directory di output ogni volta che viene creato il progetto (in VS -> Esplora soluzioni -> tasto destro del mouse -> seleziona 'Proprietà' -> Avanzate -> Copia nella directory di output -> seleziona 'Copia sempre')

  2. Installa il seguente pacchetto nuget nel mio progetto:

    • Microsoft.Extensions.Configuration.Json
  3. Aggiungi quanto segue a Program.cs (o ovunque Main()si trovi):

    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
    
        var configuration = builder.Build();
    
        // rest of code...
    }
  4. Quindi leggi i valori usando uno dei seguenti modi:

    string myKey1 = configuration["myKey1"];
    Console.WriteLine(myKey1);
    
    string foo = configuration.GetSection("foo").Value;
    Console.WriteLine(foo);

Ulteriori informazioni: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration#simple-configuration


1
Come ho notato, Microsoft non usa IConfigurationRoot nei suoi esempi, ma usa IConfiguration.
aligin,

3
IConfigurationRootè ancora disponibile in .NET Core 2.0 . Eredita da IConfigurationma è considerato un caso derivato che non è comunemente usato . Indipendentemente da ciò, l'esempio di codice è stato aggiornato per non includerlo ed evitare qualsiasi confusione.
Ray

10
2 note: al punto 4, hai solo bisogno di Microsoft.Extensions.Configuration.Json ... Includerà gli altri 2 per impostazione predefinita. Secondo: se vuoi caricare una sezione su un oggetto, è utile sapere: var options = new FooOptions (); ConfigurationBinder.Bind (configuration.GetSection ("pippo"), opzioni); Avrai bisogno di Microsoft.Extensions.Options.ConfigurationExtensions
Yepeekai

1
public class FooOptions {stringa pubblica myKey1 {get; set;} stringa pubblica myKey2 {get; set;}}
Yepeekai

2
Strumenti> NuGet Package Manager> Console gestore pacchetti .. .. Installa pacchetto Microsoft.Extensions.Configuration .. Installa pacchetto Microsoft.Extensions.Configuration.FileExtensions .. Installa pacchetto Microsoft.Extensions.Configuration.Json
Manohar Reddy Poreddy

19

Se si utilizza Microsoft.Extensions.Hosting(versione 2.1.0+) per ospitare la console app e asp.net nucleo app, tutte le configurazioni vengono iniettati con HostBuilder's ConfigureAppConfiguratione ConfigureHostConfigurationmetodi. Ecco la demo su come aggiungere le appsettings.jsonvariabili di ambiente e:

    var hostBuilder = new HostBuilder()
        .ConfigureHostConfiguration(config =>
        {
            config.AddEnvironmentVariables();

            if (args != null)
            {
                // enviroment from command line
                // e.g.: dotnet run --environment "Staging"
                config.AddCommandLine(args);
            }
        })
        .ConfigureAppConfiguration((context, builder) =>
        {
            var env = context.HostingEnvironment;
            builder.SetBasePath(AppContext.BaseDirectory)
            .AddJsonFile("appsettings.json", optional: false)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            // Override config by env, using like Logging:Level or Logging__Level
            .AddEnvironmentVariables();

        })
        ... // add others, logging, services
        //;

Per compilare il codice sopra, è necessario aggiungere questi pacchetti:

<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0" />

Come viene determinato l'ambiente? Se creo un profilo in launchSettings, in realtà imposta ASPNETCORE_ENVIRONMENTma context.HostingEnvironment.EnvironmentNamenon viene impostato correttamente
Sinaesthetic

Dovresti usare l'ambiente come chiave, controlla questo codice: github.com/aspnet/Hosting/blob/dev/src/…
Feiyu Zhou

@FeiyuZhou è un anello morto
Auspex,

Non è tutto di questa soluzione dopo new HostBuilder()ridondante? Non HostBuilderfa tutto internamente?
Auspex,

@Auspex Dipende da come si definisce l'app console. Se è necessario definire configurazioni personalizzate, è necessario impostare in questo modo. Ecco il documento per dotnet core 3.0: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
Feiyu Zhou

10

Mi sono sbagliato. È possibile utilizzare il nuovo ConfigurationBuilderda un'applicazione console netcore.

Vedere https://docs.asp.net/en/latest/fundamentals/configuration.html per un esempio.

Tuttavia, solo il core aspnet ha l'immediata iniezione di dipendenza, quindi non hai la possibilità di avere impostazioni di configurazione fortemente tipizzate e di iniettarle automaticamente usando IOptions.


9
Questa risposta è valida, ma dovrebbe contenere il codice necessario, quindi nessun voto.
Matyas,

4
Tutto ciò che serve è aggiungere il pacchetto: Microsoft.Extensions.Optionse chiamareservice.AddOptions();
Bruno Garcia il

2
L'intera (molto lunga) pagina collegata sembra essere correlata ad ASP.NET, con la menzione di "WebHost" in ogni esempio. Sono arrivato a questa domanda SO dopo aver trovato la pagina collegata e pensando "ok, questo è ASP.NET, che dire delle app console".
mackenir,

È un po 'strano, @mackenir, perché in 3.0 è stato tutto refactored in modo che sia tutto solo Host! L'unico riferimento a WebHost stesso è di farti riferimento alla documentazione 2.2. Avrebbero potuto essere un po 'più chiari sul fatto che le ConfigureWebHostDefaults()chiamate negli esempi sono facoltative e solo per le app Web.
Auspex,

4

È qualcosa del genere, per un'applicazione console core dotnet 2.x:

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

È possibile iniettare ILoggerFactory, IConfiguration in SomeService.


2

Su .Net Core 3.1 dobbiamo solo fare questi:

static void Main(string[] args)
{
  var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
}

L'uso di SeriLog sarà simile a:

using Microsoft.Extensions.Configuration;
using Serilog;
using System;


namespace yournamespace
{
    class Program
    {

        static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
            Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();

            try
            {
                Log.Information("Starting Program.");
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Program terminated unexpectedly.");
                return;
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    }
}

E la sezione Serilog appsetings.json per la generazione giornaliera di un file sarà simile a:

  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Logs\\Program.json",
          "rollingInterval": "Day",
          "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
        }
      }
    ]
  }

dopo aver provato tutte quelle sintassi da tutto il Web, la tua è quella che ha funzionato per me ed è così semplice.
GaneshT

Sono contento che ti abbia aiutato.
Ernest,

1

È possibile utilizzare la libreria LiteWare.Configuration per questo. È molto simile all'originale .NET Framework ConfigurationManagere funziona con .NET Core / Standard. Per quanto riguarda il codice, finirai con qualcosa del tipo:

string cacheDirectory = ConfigurationManager.AppSettings.GetValue<string>("CacheDirectory");
ulong cacheFileSize = ConfigurationManager.AppSettings.GetValue<ulong>("CacheFileSize");

Disclaimer: sono l'autore di LiteWare.Configuration.


0

Accumulando ... simile al post di Feiyu Zhou. Qui sto aggiungendo il nome della macchina.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
          .ConfigureAppConfiguration((context, builder) =>
          {
            var env = context.HostingEnvironment;
            var hostname = Environment.MachineName;
            builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{hostname}.json", optional: true, reloadOnChange: true);
            builder.AddEnvironmentVariables();
            if (args != null)
            {
              builder.AddCommandLine(args);
            }
          })
        .UseStartup<Startup>();
  }

0

Installa questi pacchetti:

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Binder
  • Microsoft.Extensions.Configuration.EnvironmentVariables
  • Microsoft.Extensions.Configuration.FileExtensions
  • Microsoft.Extensions.Configuration.Json

Codice:

static void Main(string[] args)
    {
        var environmentName = Environment.GetEnvironmentVariable("ENVIRONMENT");
        Console.WriteLine("ENVIRONMENT: " + environmentName);

        var builder = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json", false)
           .AddJsonFile($"appsettings.{environmentName}.json", true)
           .AddEnvironmentVariables();

        IConfigurationRoot configuration = builder.Build();
        var mySettingsConfig = configuration.Get<MySettingsConfig>();

        Console.WriteLine("URL: " + mySettingsConfig.Url);
        Console.WriteLine("NAME: " + mySettingsConfig.Name);

        Console.ReadKey();
    }

Classe MySettingsConfig:

public class MySettingsConfig
{
    public string Url { get; set; }
    public string Name { get; set; }
}

Le tue app possono essere semplici come questa: inserisci qui la descrizione dell'immagine

Inoltre, impostare i file delle app su Contenuto / Copia se più recenti: soddisfare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.