.NET Core

Configuring Dependency Injection in .NET Core Console Applications

.NET Core console applications do not have a startup file to register the dependencies.

In this post, we’ll see how we can create a dependency injection setup in .net core console applications.

A use case for this post

For this post, let’s create two services one that gives a message (MessageService) and the other to print a message (PrinterService).

The PrinterService has a Print method to print the message received from the MessageService. So, the PrinterService depends on the MessageService.

PrinterService uses MessageService

Here are the two services with code.

PrinterService.cs

using System;

namespace DIInConsole
{
    public interface IPrinterService
    {
        void PrintMessage();
    }

    public class PrinterService : IPrinterService
    {
        private IMessageService _messageService;
        public PrinterService(IMessageService messageService)
        {
            _messageService = messageService;
        }

        public void PrintMessage()
        {
            Console.WriteLine(_messageService.GetMessage());
        }
    }
}

MessageService.cs

using System;

namespace DIInConsole
{
    public interface IMessageService
    {
        MessageService MessageService { get; set; }

        string GetMessage();
    }

    public class MessageService : IMessageService
    {
        public string GetMessage()
        {
            return "This is a simple message.";
        }
    }
}

using ServiceCollection in the Program.cs file

Before we register our services, we’ve to install the Microsoft Dependency Injection package from Nuget.

With .NET CLI, you can install the package using the following command.

dotnet add package Microsoft.Extensions.DependencyInjection --version 3.1.4

We will use the ServiceCollection class in the above package to register our services to the DI container.

Here is our registration code for registering IMessageService and IPrinterService services.

 var serviceCollection = new ServiceCollection();
 serviceCollection.AddTransient<IMessageService, MessageService>();
 serviceCollection.AddTransient<IPrinterService, PrinterService>();

Once we register our services with the extension methods (AddTransient, AddScoped, AddSingleton), we will call the BuildServiceProvider on the serviceCollection object to return an instance of ServiceProvider.

var serviceProvider = serviceCollection.BuildServiceProvider();

With the ServiceProvider instance, we can get our service(s) from the registered services.

We will call GetRequiredService or GetService on the serviceProvider object to get our required service and invoke our method to get the output.

serviceProvider.GetService<IPrinterService>().PrintMessage();

That’s it! You should see our sample output in the console.

Miscellaneous Info.

What BuildServiceProvider does?

The BuildServiceProvider will just return a new instance of the ServiceProvider taking ServiceCollection instance as an argument in the constructor.

The BuildServiceProvider is just an extension method on the ServiceProvider class. Here is the original source code from github.

public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    if (options == null)
    {
        throw new ArgumentNullException(nameof(options));
    }

    return new ServiceProvider(services, options);
}

Difference between GetRequiredService and GetService

GetService() returns null if a service does not exist, GetRequiredService() throws an exception instead. If you’re using a third-party container, use GetRequiredService where possible – in the event of an exception, the third party container may be able to provide diagnostics so you can work out why an expected service wasn’t registered.

– Andrew Lock post on the difference

References

DI in Console applications
Difference between GetService and GetRequiredService in aspnet core
BuildServiceProvider source from github

Disqus Comments Loading...
Share
Published by
Karthik Chintala

Recent Posts

2 Good Tools To Test gRPC Server Applications

In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More

2 years ago

Exploring gRPC project in ASP.NET Core

In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More

2 years ago

Run dotnet core projects without opening visual studio

In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More

2 years ago

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More

2 years ago

Multiple authorization handlers for the same requirement in ASP.NET Core

We saw how we could set up policy-based authorization in our previous article. In this… Read More

2 years ago

Policy-Based Authorization in ASP.NET Core

What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More

2 years ago

This website uses cookies.