web-dev-qa-db-fra.com

Passez des arguments de ligne de commande à la classe de démarrage dans ASP Core

J'ai des arguments transmis via la ligne de commande

private static int Main(string[] args)
{

    const string PORT = "12345"    ;

    var listeningUrl = $"http://localhost:{PORT}";

    var builder = new WebHostBuilder()
        .UseStartup<Startup>()
        .UseKestrel()
        .UseUrls(listeningUrl);

    var Host = builder.Build();
    WriteLine($"Running on {PORT}");
    Host.Run();

    return 0;
}

L'un de ces arguments est un répertoire de sortie de journalisation. Comment puis-je obtenir cette valeur dans ma classe Startup pour pouvoir écrire dans ce répertoire lorsque je reçois une demande?

Je voudrais éviter d'utiliser une classe statique. Un service qui fournit la valeur serait-il la bonne façon? Si oui, comment puis-je obtenir des services injectés dans mon middleware?

14
BanksySan

Vous devriez pouvoir utiliser l'extension AddCommandLine(). Installez d'abord le package Nuget Microsoft.Extensions.Configuration.CommandLine et assurez-vous que l'importation est correcte:

using Microsoft.Extensions.Configuration;

Mettez à jour votre méthode Main pour inclure la nouvelle configuration:

var config = new ConfigurationBuilder()
    .AddJsonFile("hosting.json", optional: true) //this is not needed, but could be useful
    .AddCommandLine(args)
    .Build();

var builder = new WebHostBuilder()
    .UseConfiguration(config)  //<-- Add this
    .UseStartup<Startup>()
    .UseKestrel()
    .UseUrls(listeningUrl);

Maintenant, vous traitez les options de ligne de commande comme une configuration:

dotnet run /MySetting:SomeValue=123

Et lisez dans le code:

var someValue = Configuration.GetValue<int>("MySetting:SomeValue");
15
DavidG

Dotnet Core 2

Vous n'avez pas besoin de la plupart du code comme dans dotnet core 1.0 pour y parvenir. AddCommandLinearguments sont automatiquement injectés lorsque vous BuildWebHost en utilisant la syntaxe suivante

Étape 1.

 public static IWebHost BuildWebHost(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
        }

Étape 2. Injectez des configurations à Startip.cs à l'aide de DI à l'aide du code suivant

public class Startup
    {
        private readonly IConfiguration Configuration;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

Étape 3. Accédez à vos arguments à l'aide de l'objet configurations.

 var seed = Configuration.GetValue<bool>("seed");
        Console.WriteLine("seed :" +seed);

Étape 4. Démarrez l'application avec des arguments

 dotnet run seed=True
7
Charith

Réponse d'ASP.NET Core 2:

Modifiez le Program.cs par défaut pour être:

using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
                config.AddEnvironmentVariables();
                config.AddCommandLine(args);
            })
            .UseStartup<Startup>()
            .Build();
}

J'ai supprimé d'autres bits juste pour faciliter l'explication de la configuration.

Notez la ligne .AddCommandLine(args) dans le générateur de configuration.

Contrairement à la réponse de @ BanksySan, vous n'avez PAS besoin de créer une propriété statique, laissez plutôt DI injecter l'IConfiguration dans la classe de démarrage.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    private IConfiguration Configuration { get; }

Vous pouvez maintenant utiliser les entrées de configuration de n'importe lequel des fournisseurs de configuration, fichier, variables env et ligne de commande.

Exemple:

dotnet run --seed true

    public void Configure(IApplicationBuilder app)
    {
        app.UseExceptionHandler("/Home/Error");

        var seed = Configuration.GetValue<bool>("seed");
        if (seed)
            SeedData.Initialize(app);

        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }

J'espère que cela aide quelqu'un plus loin.

5
Allan

réponse de DavidG est correct, mais il me manquait encore quelques pièces du puzzle.

Il y a deux packages Nuget dont vous avez besoin:

  1. Microsoft.Extensions.Configuration.Binder
  2. Microsoft.Extensions.Configuration.CommandLine

Parce que nous voulons les arguments de ligne de commande, nous devons créer la configuration dans la Main(string[]).

using Microsoft.Extensions.Configuration;

class Program
{
    private static int Main(string[] args)
    {
        const string PORT = "12345";

        var listeningUrl = $"http://localhost:{PORT}";
        var configuration = new ConfigurationBuilder()
                            .AddCommandLine(args)
                            .Build();
        // Set the `static` `Configuration` property on the `Startup` class.
        Startup.Configuration = configuration;

        var builder = new WebHostBuilder()
            .UseStartup<Startup>()
            .UseKestrel()
            .UseSetting("Message", "Hello World")
            .UseUrls(listeningUrl);

        var Host = builder.Build();
        WriteLine($"Running on {listeningUrl}");
        Host.Run();

        return SUCCESS_EXIT_CODE;
    }
}

La classe Startup est:

using Microsoft.Extensions.Configuration;

public class Startup
{
    public static IConfiguration Configuration { get; set; }


    public void Configure(IApplicationBuilder app)
    {
        foreach (var c in Configuration.AsEnumerable())
            Console.WriteLine($"{c.Key,-15}:{c.Value}");
    }
}

Si l'argument de la commande est --port 6000 outputDirectory C:\Temp, Cela affichera:

port            :6000
outputDirectory :C:\Temp
4
BanksySan