Dependency Injection in a Console App

I create a lot of Console applications, mainly for prototypes or small one-off jobs, but sometimes I want to to do more. For those applications I want to use Dependency Injection and things like appsettings and Entity Framework.

To save time on trying to remember how to do it every time, and because google results for DI in Console Apps are slim pickings and spread across differing versions, I decided to record it here for myself.

I am doing this example in a .Net Core Console App using .NET 7.0

Add the required packages

PM> Install-Package Microsoft.Extensions.DependencyInjection
PM> Install-Package Microsoft.Extensions.Hosting

# if you are adding an EF DataContext then this is required
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer
# it will also install Microsoft.EntityFrameworkCore

# if you want to use logging then add this
PM> Install-Package Microsoft.Extensions.Logging

Add the required classes

For this example I have a class to run my prototype, and I have added a DataContext to that class.

The idea here is that each class will log information to prove it works.

internal class TestDBDataContext :DbContext
{
    private readonly ILogger<TestDBDataContext> _logger;

    public TestDBDataContext(ILoggerFactory loggerFactory, DbContextOptions<TestDBDataContext> options) : base(options)
    {
        _logger = loggerFactory.CreateLogger<TestDBDataContext>();

        // get and display the connection string
        var extension = options.FindExtension<SqlServerOptionsExtension>();
        _logger.LogInformation($"Connection String: {extension.ConnectionString}");
    }
}
internal class PrototypeRunner
{
    private readonly ILogger<PrototypeRunner> _logger;
    private readonly TestDBDataContext _dbContext;

    public PrototypeRunner(ILoggerFactory loggerFactory, TestDBDataContext dbContext)
    {
        _logger = loggerFactory.CreateLogger<PrototypeRunner>();
        _dbContext = dbContext;
    }

    public void RunPrototype()
    {

        _logger.LogInformation("Running Prototype");
        // debug won't log with the default appsettings level of Information
        _logger.LogDebug("Debugging Prototype");
    }
}
{
  "ConnectionStrings": {
    "TestDB": "Data Source=TestServer1; Initial Catalog=TestDb; User Id=TestUser; Password=UserPassword; TrustServerCertificate=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

About the builder

The big thing to remember is that it seems that the equivalent of WebApplication.CreateBuilder() for Console Apps is Host.CreateApplicationBuilder().

I have seen a few articles that use Host.CreateDefaultBuilder(), but the use of that is quite different to either of the above methods.

According to this Mircosoft article Host.CreateApplicationBuilder() sets the following defaults (as well as others)…

  • Set the ContentRootPath to the result of GetCurrentDirectory().
  • Load app IConfiguration from ‘appsettings.json’ and ‘appsettings.[EnvironmentName].json’.
  • Configure the ILoggerFactory to log to the console, debug, and event source output.

Tying it all together

This is what the program.cs should look like

using [Your App Namespace Here]
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;

// Use Application Builder
var builder = Host.CreateApplicationBuilder(args);
// Configure the services
builder.Services
    .AddLogging()
    .AddTransient<PrototypeRunner>()
    .AddDbContext<TestDBDataContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("TestDB")));


// build it into the app

var app = builder.Build();

// get the logger
var logger = app.Services.GetService<ILoggerFactory>().CreateLogger<Program>();
logger.LogInformation("Starting application");


// get the starting class and run it
var runner = app.Services.GetService<PrototypeRunner>();
runner.RunPrototype();

Console.ReadKey();

The Output

Console App Output - DI

Leave a Reply

Your email address will not be published. Required fields are marked *