Note: this article is published on 07/09/2024.
These will be a series of articles about Design Patterns. We start from MVC Pattern:
- Design Pattern (0), Overview
- Design Pattern (1), MVC
- Design Pattern (2), MVVM
- Design Pattern (3), Singleton
- Singleton vs. Static Class: Design Pattern (3-1), Differences between Singleton and Static Class
- Why Singleton Class is Sealed
- Lazy Loading and Eager Loading in Stingleton Design Pattern
- Design Pattern (4), Desposal
- Design Pattern (5), Dependency Injection
A: Introduction
.NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. Inversion of Control is a principle in software engineering which transfers the control of objects or portions of a program to a container or framework.
This article will be an implementation of Dependency Injection for a Console app with a constructor injection and associated with a .NET Core built in container to handle the service lifetimes.
- A: Introduction
- B: Setup Environment
- C: Setup the Program
- D: Run and Result
B: Setup Environment:
Open a console App by Visual Studio 2022, Version 17.10.3, current on 06/30/2024

Project Name as ConsoleDI.Example

Framework: .NET 8.0 (Long Term Support)

Running:

In this example, the Microsoft.Extensions.Hosting NuGet package is required to build and run the app. Adding:

C: Setup the Program:
After the program is setting up, we will have these:

Now we go step by step according to the process of setting up a Dependency Injection,
- Setup Interface
- Make a service
- Register the service to a Container (.Net Core Default DI Container)
- Make a client
1. Setup Interfaces:
- IReportServiceLifetime --- Line 5
- A
Guid Idproperty that represents the unique identifier of the service. - A ServiceLifetime property that represents the service lifetime.
- A
- IExampleSingletonService : IReportServiceLifetime --- Line 11
- IExampleScopedService : IReportServiceLifetime --- Line 16
- IExampleTransientService : IReportServiceLifetime --- Line 21
using Microsoft.Extensions.DependencyInjection;
namespace ConsoleDI.Example;
public interface IReportServiceLifetime
{
Guid Id { get; }
ServiceLifetime Lifetime { get; }
}
public interface IExampleSingletonService : IReportServiceLifetime
{
ServiceLifetime IReportServiceLifetime.Lifetime => ServiceLifetime.Singleton;
}
public interface IExampleScopedService : IReportServiceLifetime
{
ServiceLifetime IReportServiceLifetime.Lifetime => ServiceLifetime.Scoped;
}
public interface IExampleSingletonService : IReportServiceLifetime
{
ServiceLifetime IReportServiceLifetime.Lifetime => ServiceLifetime.Singleton;
}
Note:
For convenience, I combine the four saperated pages for interfaces in one as above:

2. Make Services:
Implementations for the interfaces: Initializing their Id property with the result of Guid.NewGuid().
- internal sealed class ExampleSingletonService : IExampleSingletonService --- Line 3
- internal sealed class ExampleScopedService : IExampleScopedService --- Line 8
- internal sealed class ExampleTransientService : IExampleTransientService --- Line 13
Each implementation is defined as internal sealed and implements its corresponding interface. For example, ExampleSingletonService implements IExampleSingletonService.
namespace ConsoleDI.Example;
internal sealed class ExampleSingletonService : IExampleSingletonService
{
Guid IReportServiceLifetime.Id { get; } = Guid.NewGuid();
}
internal sealed class ExampleScopedService : IExampleScopedService
{
Guid IReportServiceLifetime.Id { get; } = Guid.NewGuid();
}
internal sealed class ExampleTransientService : IExampleTransientService
{
Guid IReportServiceLifetime.Id { get; } = Guid.NewGuid();
}
Note:




Join the conversation! Your thoughts help the community grow.