.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.
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
– Andrew Lock post on the difference
GetService()
returnsnull
if a service does not exist,GetRequiredService()
throws an exception instead. If you’re using a third-party container, useGetRequiredService
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.
References
– DI in Console applications
– Difference between GetService and GetRequiredService in aspnet core
– BuildServiceProvider source from github
Karthik is a passionate Full Stack developer working primarily on .NET Core, microservices, distributed systems, VUE and JavaScript. He also loves NBA basketball so you might find some NBA examples in his posts and he owns this blog.
Pingback: Dew Drop – June 5, 2020 (#3212) | Morning Dew