Configuración de ASP.NET Core para la aplicación de consola .NET Core


Respuestas:


76

Puede usar este fragmento de código. Incluye Configuración y 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>();

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

Ah, y no olvides agregar el proyecto .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
Esta respuesta no es ideal. Usar en Directory.GetCurrentDirectory()lugar de AppContext.BaseDirectory. No debería haber necesidad de hackear después.
Matyas

1
O establezca la propiedad "Copiar al directorio de salida" en "Copiar si es más reciente" en Visual Studio para los archivos JSON.
BuddhiP

Para que el directorio base funcione en Web, Console y Winforms, puede usar este enfoque stackoverflow.com/a/33675039/1818723
Pawel Cioch

Gary Woodfine describió esto en detalle con un muy buen estilo en esta publicación: garywoodfine.com/configuration-api-net-core-console-application
Javad Norouzi

@javad Solo en parte; Terminé aquí porque quería la parte DI, que él prometió pero no he encontrado. Tampoco mostró cómo usar múltiples archivos de configuración como lo hace este ejemplo.
Auspex

232

Para una aplicación de consola .NET Core 2.0, hice lo siguiente:

  1. Cree un nuevo archivo llamado appsettings.json en la raíz del proyecto (el nombre del archivo puede ser cualquier cosa)
  2. Agregue mi configuración específica a ese archivo como json. Por ejemplo:
{
  "myKey1" :  "my test value 1", 
  "myKey2" :  "my test value 2", 
  "foo" :  "bar" 
}
  1. Configure para copiar el archivo al directorio de salida siempre que se construya el proyecto (en VS -> Explorador de soluciones -> haga clic con el botón derecho en el archivo -> seleccione 'Propiedades' -> Avanzado -> Copiar al directorio de salida -> seleccione 'Copiar siempre')

  2. Instale el siguiente paquete nuget en mi proyecto:

    • Microsoft.Extensions.Configuration.Json
  3. Agregue lo siguiente a Program.cs (o donde Main()se encuentre):

    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
    
        var configuration = builder.Build();
    
        // rest of code...
    }
  4. Luego lea los valores utilizando cualquiera de las siguientes formas:

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

Más información: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration#simple-configuration


1
Como noté, Microsoft no usa IConfigurationRoot en sus ejemplos, sino IConfiguration.
alineación

3
IConfigurationRoottodavía está disponible en .NET Core 2.0 . Hereda de, IConfigurationpero se considera un caso derivado que no se usa comúnmente . En cualquier caso, el ejemplo de código se ha actualizado para no incluirlo y evitar confusiones.
Ray

10
2 notas: en el punto 4, solo necesita Microsoft.Extensions.Configuration.Json ... Incluirá los otros 2 por defecto. Segundo: si desea cargar una sección en un objeto, es útil saber: var options = new FooOptions (); ConfigurationBinder.Bind (configuration.GetSection ("foo"), opciones); Necesitará Microsoft.Extensions.Options.ConfigurationExtensions
Yepeekai

1
FooOptions de clase pública {cadena pública myKey1 {get; set;} cadena pública myKey2 {get; set;}}
Yepeekai

2
Herramientas> NuGet Package Manager> Package Manager Console .. .. Install-Package Microsoft.Extensions.Configuration .. Install-Package Microsoft.Extensions.Configuration.FileExtensions .. Install-Package Microsoft.Extensions.Configuration.Json
Manohar Reddy Poreddy

19

Si utiliza Microsoft.Extensions.Hosting(versión 2.1.0+) para alojar su aplicación de consola y asp.net aplicación central, todas las configuraciones son inyectados con HostBuilder's ConfigureAppConfigurationy ConfigureHostConfigurationmétodos. Aquí está la demostración sobre cómo agregar las appsettings.jsonvariables de entorno:

    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
        //;

Para compilar el código anterior, debe agregar estos paquetes:

<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" />

¿Cómo se determina el medio ambiente? Si creo un perfil en launchSettings, en realidad se establece ASPNETCORE_ENVIRONMENTpero luego context.HostingEnvironment.EnvironmentNameno se configura correctamente
Sinaesthetic

Debe usar el entorno como clave, verifique este código: github.com/aspnet/Hosting/blob/dev/src/…
Feiyu Zhou

@FeiyuZhou que es un enlace muerto
Auspex

¿No es toda esta solución después de new HostBuilder()redundante? ¿No HostBuilderlo hace todo internamente?
Auspex

@Auspex Depende de cómo defina su aplicación de consola. Si necesita definir configuraciones personalizadas, debe establecerlas así. Aquí está el documento para dotnet core 3.0: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
Feiyu Zhou

10

Estaba equivocado. Puede usar el nuevo ConfigurationBuilderdesde una aplicación de consola netcore.

Ver https://docs.asp.net/en/latest/fundamentals/configuration.html para ver un ejemplo.

Sin embargo, solo el núcleo de aspnet tiene una inyección de dependencia lista para usar, por lo que no tiene la capacidad de tener configuraciones de configuración fuertemente tipadas e inyectarlas automáticamente usando IOptions.


9
Esta respuesta es válida, pero debe contener el código necesario, por lo tanto, no hay voto a favor.
Matyas

44
Todo lo que necesita es añadir el paquete: Microsoft.Extensions.Optionsy llamadaservice.AddOptions();
Bruno García

2
Toda la página vinculada (muy larga) parece estar relacionada con ASP.NET, con mención de "WebHost" en cada ejemplo. Llegué a esta pregunta SO después de encontrar la página vinculada y pensar "ok, eso es ASP.NET, ¿qué pasa con las aplicaciones de consola".
mackenir

Eso es un poco extraño, @mackenir, porque en 3.0 todo ha sido refactorizado para que todo sea solo Host. La única referencia a WebHost en sí es señalarle la documentación 2.2. Podrían haber sido un poco más claros que las ConfigureWebHostDefaults()llamadas en los ejemplos son opcionales, y solo para aplicaciones web.
Auspex

4

Es algo como esto, para una aplicación de consola central 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();

El podría inyectar ILoggerFactory, IConfiguration en el SomeService.


2

En .Net Core 3.1 solo necesitamos hacer esto:

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

El uso de SeriLog se verá así:

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

Y la sección Serilog appsetings.json para generar un archivo diariamente se verá así:

  "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"
        }
      }
    ]
  }

después de probar toda esa sintaxis de toda la web, la suya fue la que funcionó para mí, y es muy simple.
GaneshT

Me alegra que te haya ayudado.
Ernest

1

Puede usar la biblioteca LiteWare.Configuration para eso. Es muy similar al .NET Framework original ConfigurationManagery funciona para .NET Core / Standard. En cuanto al código, terminará con algo como:

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

Descargo de responsabilidad: soy el autor de LiteWare.Configuration.


0

Simplemente acumulando ... similar a la publicación de Feiyu Zhou. Aquí estoy agregando el nombre de la máquina.

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

Instale estos paquetes:

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

Código:

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

MySettingsConfig Class:

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

Sus ajustes de aplicaciones pueden ser tan simples como esto: ingrese la descripción de la imagen aquí

Además, configure los archivos de configuración de la aplicación en Contenido / Copiar si es más reciente: contenido

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.