Support ASP.NET Core Generic Hosts
See original GitHub issueASP.NET Core Generic Hosts are a great way to handle background tasks. Unfortunately, Generic Hosts don’t do anything fancy for command line parsing. That’s where CommandLineUtils comes in!
The basic idea is that CommandLineUtils should parse the command line arguments to figure out which IHostedService
to register.
Attribute Pattern
In the attribute pattern, I suggest that CommandLineUtils registers the matched type using the host’s AddHostedService
if the matched type is an IHostedService
. For example:
public class Program : IHostedService
{
public static int Main(string[] args)
=> await new HostBuilder()
.UseCommandLineApplication<Program>(args) // CommandLineUtils extension!
.RunConsoleAsync();
[Option(Description = "The subject")]
public string Subject { get; }
public async Task StartAsync(CancellationToken cancellationToken)
{
var subject = Subject ?? "world";
Console.WriteLine($"Hello {subject}!");
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Fluent apps
For fluent apps, I suggest we add some extensions on IHostBuilder
:
public class Program
{
public static Task Main(string[] args)
{
await new HostBuilder()
.UseCommandLineApplication(args, (hostContext, services, app) =>
{
app.HelpOption();
var optionSubject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
// (1/3) "Traditional" approach:
app.OnExecute(services =>
{
var subject = optionSubject.HasValue()
? optionSubject.Value()
: "world";
// This is a little icky. We pass the subject option through the service's constructor:
services.AddHostedService<HelloService>(provider => new HelloService(subject));
});
// (2/3) Alternate approach:
// This creates a delegate-based `BackgroundService` that captures local options
app.RunBackgroundService(CancellationToken token =>
{
var subject = optionSubject.HasValue()
? optionSubject.Value()
: "world";
Console.WriteLine($"Hello {subject}!");
});
// (3/3) Stretch goal:
// Something else I'd like are short-lived commands that do a task
// and then automatically shut down the .NET Generic Host after completion
app.RunCommand(CancellationToken token =>
{
var subject = optionSubject.HasValue()
? optionSubject.Value()
: "world";
// After this returns, the host is shutdown gracefully.
Console.WriteLine($"Hello {subject}!");
});
})
.RunConsoleAsync();
}
}
public class HelloService : BackgroundService
{
private readonly string _subject;
public HelloService(string subject)
{
_subject = subject;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Console.WriteLine($"Hello {_subject}!");
}
}
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (6 by maintainers)
Top Results From Across the Web
NET Generic Host in ASP.NET Core
Use .NET Core Generic Host in ASP.NET Core apps. Generic Host is responsible for app startup and lifetime management.
Read more >Understanding .NET Generic Host Model
ASP.NET Core apps configure and launch a host. The host is responsible for app startup and lifetime management. At a minimum, the host...
Read more >NET Core Startup class & Generic Host
NET Generic Host, which is a non-web version of the WebHost that runs ASP.NET Core. In ASP.NET Core 3.0 and 3.1, they moved...
Read more >Building a Console App with .NET Generic Host | David's Blog
The .NET Generic Host is a feature which sets up some convenient patterns for an application including those for dependency injection (DI), ...
Read more >Using HostBuilder and the Generic Host in .NET Core ...
NET Core 2.1 is the new “generic” Host which enables developers to easily set up cross-cutting concerns such as logging, configuration and ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@natemcmaster , i submitted the pull req. I created it as a separate package using the namespace you suggested (i think it is the correct namespace as it is basically an extension of Hosting that adds the CLI stuff, though the inverse is also true). I updated the dependency injection documentation to include a section for using generic host, and added a sample. However, I did not have any unit tests, so if that is necessary, i will have to figure out how to make that happen. Anyway, let me know what you think.
I really like this idea. I don’t have time to work on it right now, so I’ll mark it as up for grabs. If you want to get started on an implementation, let me know.