Dependency Injection in .NET Core Console app using Generic HostBuilder

Dependency Injection in Console

In this post, we shall learn how to perform dependency injection in the .NET Core Console application using Generic HostBuilder.

We already learned one more approach of DI using Service collection and ServiceProvider in Console Application.

Until now and still many implementation-prefer and rely on service collection classes for registering the dependency and using it through DI container.

Today in this article, we will cover below aspects,

Let’s look into how to use generic HostBuilder to create DI Container and inject the required dependency within the Console app .NET Core application.

Getting started

Here I am using .NET Core 3.1 Console application,

Similar to the already discussed article in the previous post on DI here is the project structure we shall be dealing with. I shall be using the same sample and performing DI but we will be using .NET Core 3.1.

Dependency Injection in Console app

Creating Generic HostBuilder

Generic HostBuilder was introduced in .NET Core 2.1 and designed to be used for both Non-HTTP and HTTP workloads.

The HostBuilder class is available from the following namespace,

using Microsoft.Extensions.Hosting;

HostBuilder implements the IHostBuilder interface.

Please install the NuGet package from Nuget Package manager or PMC,

PM> Install-Package Microsoft.Extensions.Hosting -Version 3.1.1

DI Container

Please create Generic HosBuilder and register the dependencies that need to inject. These changes can be implemented in the Main() method.

 var builder = new HostBuilder()
               .ConfigureServices((hostContext, services) =>
               {

                   services.AddLogging(configure => configure.AddConsole());
                   services.AddTransient<MyApplication>();
                   services.AddScoped<IBusinessLayer, BusinessLayer>();
                   services.AddSingleton<IDataAccessLayer, CDataAccessLayer>(); 

               })

Initialize the Host

Initialize the Host with all dependencies,

 _host = builder.Build();

OR

By using generic host builder CreateDefaultBuilder

host = Host.CreateDefaultBuilder()
           .ConfigureServices((hostContext, services) =>
           {

           }).Build();

Here we are considering class MyApplication as the entry point for all other classes and business objects and their action.

However, you can add an additional layer addressing the separation of concern if needed.

All the services registered using HostBuilder are now available to use as per the need and can be injected using Construction injection.

The lifetime management of those services will be taken care of by HostBuilder and we need not worry about disposing of them.

Initialize the CreateScope

Please add the below code in the Main() method,

 using (var serviceScope = host.Services.CreateScope())
            {
                var services = serviceScope.ServiceProvider;

                try
                {
                    var myService = services.GetRequiredService<MyApplication>();
                    await myService.Run();

                    Console.WriteLine("Success");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error Occured");
                }
            }

Below is the class MyApplication executing the business workflow.

We are injecting logger and business objects as defined and registered in the scope using the HostBuilder DI container.

public class MyApplication
    {
        private readonly ILogger _logger;
        private readonly IBusinessLayer _business;
        public MyApplication(ILogger<MyApplication> logger, IBusinessLayer business)
        {
            _logger = logger;
            _business = business;
        }

        internal async Task Run()
        {
            _logger.LogInformation("Application {applicationEvent} at {dateTime}", "Started", DateTime.UtcNow);

            _business.PerformBusiness();

            _logger.LogInformation("Application {applicationEvent} at {dateTime}", "Ended", DateTime.UtcNow);

            Console.WriteLine("PRESS <ENTER> TO EXIT");
            Console.ReadKey();
        }
    }

Let’s execute the application and capture the event and action,

Dependency Injection in Console NET Core

Note: Above console logs were intentionally made it to the console view so that events can be captured.

If interested to know on one more approach, please see below post,

Handling Start and Stop Events

Host lifetime can be controlled using the below-supported methods.

 public async Task StartAsync()
    {
        _host.StartAsync();
    }

    public async Task StopAsync()
    {
        using (_host)
        {
            await _host.StopAsync(TimeSpan.FromSeconds(10));
        }
    }

How to enable configuration loading using DI

You can very much load configuration from different sources like JSON, INI, or XML files in .NET Core Console or Windows or WPF application easily.

I have covered the loading of Apsetting.json or Custom JSON file loading in the below article in detail,

HostBuilder Vs CreateDefaultBuilder

One can create a host builder using generic host builder CreateDefaultBuilder a .NET and ASP.NET Core. It helps us to provide accessing application configuration, user secretes, getting access to environmental information by default out of the box.

Can we make the above code better?

Please let me know if you have any better suggestions and please sound off your comments below.

Summary

Today we learned one more approach for leveraging the Dependency Injection (DI) in Console application in the .NET Core ecosystem. We learned that using HostBuilder we can easily leverage DI in Desktop or Forms applications and can create highly maintainable and extensible Win Form or Desktop applications.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



3 thoughts on “Dependency Injection in Console app using generic HostBuilder – Part II

  1. Thanks a lot, this article helped me fixed a problem of using HttpClient Factory in console application. Thinking if can have this code in separate class – host.Services.CreateScope

    1. Hello TeaMohn- Thanks for the query. You can very much write Unit and integration test easily being IoC introduction brings you programming by abstraction. I shall soon put some sample examples around it.

Leave a Reply

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