dotnet preconfigured console application

For simple console apps there is no need for anything fancy

But as soon as you need logging, dependency injection and other things you will probably end up with something manualy configured

How about instead of doing everything by hands to use defaults from an web application

To do so we are going to change project sdk to "Microsoft.NET.Sdk.Web" from simple "Microsoft.NET.Sdk" it will give us access to usual builders we have in web apps

And our app may look something like:

using Foo;

// var builder = WebApplication.CreateBuilder(args); // instead pass environment name as Development in Debug mode, it will make both "Run" command from JetBrains Rider and "dotnet run" in shell commands behave the same way
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    #if DEBUG
    EnvironmentName = "Development",
    #endif
    Args = args
});

// now we have preconfigured logging, app settings, environments, etc and may register our services as usual
builder.Services.AddSingleton<IWorker, Worker>();

var app = builder.Build();

// app.Run(); // instead of running the app we will require our worker from DI container and run it, for logger and other services to recognize the flow we manually calling start/stop routines for app, otherwise logger is not fast enough to print messages (they are buffered behind the scene)
await app.StartAsync();
await app.Services.GetRequiredService<IWorker>().Work();
await app.StopAsync();

// some dummy sample worker, wrapped in a namespace just to check if logging levels from app settings will take effect
namespace Foo
{
    internal interface IWorker
    {
        Task Work();
    }

    internal class Worker : IWorker
    {
        private readonly ILogger<Worker> _logger;
        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }
        public Task Work()
        {
            _logger.LogDebug("WORKING");
            return Task.CompletedTask;
        }
    }
}

The benefits are:

  • app is preconfigured the same way we expect it to be, all logging and other stuff is added by default, environment variables and handled, etc
  • in case of need it will be dramatically easy to switch to web

The same way as we do it for web apps we may have launch settings but there is even better way which will make running app from rider and shell consistent

Having all that reduces boiler plate code of console apps dramatically, usually it is all possible vairations of cronjob

Also I do like this approach because can move code pieces between projects without being aware if that is web or console app