A colleague of mine is working on a console app, and we had a bit of a stumble. Launching the app would simply flash up an empty console window, which would then immediately close.
No breakpoints would be hit. No errors would be logged anywhere. No output.
After a few minutes of nosing around, I found the reason his app wasn't working was due to a dependency of his primary IHostedService
not being registered. Simple enough to fix.
What I want to know is; why was there no exception or error logged to the console? This would have made our lives a lot easier.
Example (knocked together very rapidly):
//[Program.cs]
namespace FooNamespace
{
internal class Program
{
static void Main(string[] args)
{
var hostBuilder = Host.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureServices((_, services) =>
{
services.AddHostedService<FooHostedService>();
//Missing dependency
//services.AddSingleton<IFooDependency, FooDependency>();
});
hostBuilder.RunConsoleAsync();
}
}
}
// [FooHostedService.cs]
namespace FooNamespace
{
internal class FooHostedService : IHostedService
{
private IFooDependency FooDependency { get; }
public FooHostedService(IFooDependency fooDependency)
{
FooDependency = fooDependency;
}
public Task StartAsync(CancellationToken cancellationToken)
{
//If the program were working, this should display a string and pause for input
Console.WriteLine("Hello, world!");
Console.ReadKey(true);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
First of all, you are missing to await the RunConsoleAsync method. And that should be enough.
Furthermore, I suggest you to use a logging library as Serilog (Serilog.AspNetCore): https://github.com/serilog/serilog/wiki/Configuration-Basics
This is an example:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
namespace FooNamespace
{
internal class Program
{
static async Task Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateBootstrapLogger();
try
{
var hostBuilder = Host.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureServices((_, services) =>
{
services.AddHostedService<FooHostedService>();
//Missing dependency
//services.AddSingleton<IFooDependency, FooDependency>();
});
await hostBuilder.RunConsoleAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, ex.Message);
}
finally
{
Log.CloseAndFlush();
}
}
}
}
In this case you would also log other types of problems, such as host building issues. See: https://nblumhardt.com/2020/10/bootstrap-logger/