Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
[erledigt] Worker Service: Abrufen von Konfigurationsparametern
pollito
myCSharp.de - Member

Avatar #avatar-3521.gif


Dabei seit:
Beiträge: 211

Themenstarter:

[erledigt] Worker Service: Abrufen von Konfigurationsparametern

beantworten | zitieren | melden

Hallo,

ich mache meine ersten Schritte mit .Net 6 und versuche einen Dienst mit Hilfe von BackgroundService zu erstellen. Die Grundlagen sind von Microsoft relativ gut beschrieben, aber eine Sache will mir nicht gelingen: Das Abrufen von Parametern im Worker Service.

In meinem Beispiel würde ich gerne die Parameter der Kommandozeile abrufen. Diese stehen auch im Worker in "Configuration" zur Verfügung, ich weiß aber nicht, wie ich den Wert programmtechnisch abrufen muss.

using BackgroundServiceTest;

IHost host = Host.CreateDefaultBuilder(args)
	.ConfigureServices(services =>
	{
		services.AddHostedService<Worker>();
	})
	.Build();

await host.RunAsync();

namespace BackgroundServiceTest
{
	public class Worker : BackgroundService
	{
		private readonly ILogger<Worker> Logger;

		public Worker(ILogger<Worker> logger, IConfiguration configuration)
		{
			Logger = logger;
			Configuration = configuration;
		}

		protected override async Task ExecuteAsync(CancellationToken stoppingToken)
		{
			while (!stoppingToken.IsCancellationRequested)
			{
				Logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
				await Task.Delay(1000, stoppingToken);
			}
		}
	}
}

Unten sieht man in [4] die Parameter der Kommandozeile (hier nur ein Stück). Nun komme ich programmtechnisch nicht auf den Wert.
Name	Wert
Configuration	{Microsoft.Extensions.Configuration.ConfigurationRoot}
◢ Providers	Count = 5
  ▶ [0]	{Microsoft.Extensions.Configuration.ChainedConfigurationProvider}
  ▶ [1]	{JsonConfigurationProvider for 'appsettings.json' (Optional)}
  ▶ [2]	{JsonConfigurationProvider for 'appsettings.Development.json' (Optional)}
  ▶ [3]	{EnvironmentVariablesConfigurationProvider Prefix: ''}
  ◢ [4]	{CommandLineConfigurationProvider}
      ◢ Args	{string[1]}
          [0]	"C:\\Daten\\Visual Studio\\Projects\\Tests\\.Net 6\\WorkerService\\Datei.txt"
      ▶ Data	Count = 0
    ▶ Nicht öffentliche Member	
  ▶ Rohdatenansicht	
▶ Nicht öffentliche Member

Klar kann ich die Kommandozeile anders ermitteln, aber die Frage gilt auch für andere mit

.ConfigureAppConfiguration(app =>
{
    ...
})
hinzugefügten Parameter.

Es wäre super, wenn jemand mir einen Tipp geben könnte.

Schönen Dank und LG
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von pollito am .
René
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1545
Herkunft: Düsseldorf

beantworten | zitieren | melden

Die Args müssen weiterhin Key-Value-Paare abbilden, einzelne Werte (z.B. nur ein Datei-Pfad) sind nicht möglich.
Den Key kannst Du dann benutzen, um den Wert zu bekommen, so wie man es mit IConfiguration so macht.
Man kann damit z.B. appsettings-Einträge durch die Kommandozeile überschreiben, muss dafür aber auch den passenden Wert verwenden.

Configuration in ASP.NET Core
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
pollito
myCSharp.de - Member

Avatar #avatar-3521.gif


Dabei seit:
Beiträge: 211

Themenstarter:

beantworten | zitieren | melden

Danke, das hat mir weitergeholfen. Wenn ich in der Kommandozeile den Dateinamen als KeyValue angebe wie z. B.
Datei="C:\\Daten\\Visual Studio\\Projects\\Tests\\.Net 6\\WorkerService\\Datei.txt"
bekomme ich
Name	Wert
Configuration	{Microsoft.Extensions.Configuration.ConfigurationRoot}
◢ Providers	Count = 5
  ▶ [0]	{Microsoft.Extensions.Configuration.ChainedConfigurationProvider}
  ▶ [1]	{JsonConfigurationProvider for 'appsettings.json' (Optional)}
  ▶ [2]	{JsonConfigurationProvider for 'appsettings.Development.json' (Optional)}
  ▶ [3]	{EnvironmentVariablesConfigurationProvider Prefix: ''}
  ◢ [4]	{CommandLineConfigurationProvider}
      ◢ Args	{string[1]}
            [0] "C:\\Daten\\Visual Studio\\Projects\\Tests\\.Net 6\\WorkerService\\Datei.txt"
      ◢ Data  Count = 1
         ◢ [0]
              Key   "Datei"
              Value "C:\\Daten\\Visual Studio\\Projects\\Tests\\.Net 6\\WorkerService\\Datei.txt"
    ▶ Nicht öffentliche Member
  ▶ Rohdatenansicht
▶ Nicht öffentliche Member

Mit

Configuration["Datei"]
bekomme ich zwar den gewünschten Wert, aber woher weiß C# in welchem der 5 Provider es suchen muss? Kann ich den Provider gezielt angeben?

Nochmals vielen Dank und LG
René
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7581
Herkunft: Waidring

beantworten | zitieren | melden

Hallo pollito,

wenn du unbedingt auf die Key-Value-Paare für die Kommandozeilen-Argumente verzichten möchtest, so kann beim Einstieg ins Programm die Befehlszeile geparst werden und ein Objekt erstellt werden, welches dann via DI als Singleton registriert wird. Dies kann im Worker geholt werden.

Ganz grob:


using BackgroundServiceTest;

IHost host = Host.CreateDefaultBuilder(args)
	.ConfigureServices(services =>
	{
		CommandLineArgs clArgs = ParseCommandLineArgs(args);
		services.AddSingleton(clArgs);
		services.AddHostedService<Worker>();
	})
	.Build();

await host.RunAsync();

Nebenbei gibt es von überall aus auch den Weg via Environment.GetCommandLineArgs(), aber das würde ich eher als Notlösung sehen.

mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7581
Herkunft: Waidring

beantworten | zitieren | melden

Hallo pollito,
Zitat von pollito
aber woher weiß C# in welchem der 5 Provider es suchen muss? Kann ich den Provider gezielt angeben?
C# ist das recht egal, solange das .NET Framework das weiß.
Die Provider bauen aufeinander auf, so dass später hinzugefügt die Werte von vorher hinzugefügten überschreiben können. Das meinte auch Palladin007 mit
Zitat von Palladin007
Man kann damit z.B. appsettings-Einträge durch die Kommandozeile überschreiben, muss dafür aber auch den passenden Wert verwenden.

Lies dir bitte die Doku nochmal durch, damit du das Verständnis dafür bekommst.

mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
pollito
myCSharp.de - Member

Avatar #avatar-3521.gif


Dabei seit:
Beiträge: 211

Themenstarter:

beantworten | zitieren | melden

@gfoidl
Vielen Dank! Du und Palladin007 haben mir weitergeholfen.
Wie kann ich den Thread als gelöst kennzeichnen?
LG
René
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7581
Herkunft: Waidring

beantworten | zitieren | melden

Hallo pollito,
Zitat
Wie kann ich den Thread als gelöst kennzeichnen?
Einen richtigen Mechanismus dafür haben wir momentan nicht, aber oftmals wird einfach dem Themen-Titel ein [erledigt] vorangestellt.
Dazu den Startbeitrag editieren, damit der Titel geändert werden kann.

Edit: sorry, hab vergessen dass das so nicht mehr geht (ging im alten Forum so).

mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers