In this post, we will do some exercises to go over the basics of DI (Dependency Injection) in ASP.NET. Accessibility Levels What's the result of the following ? code { } : { ServiceA() { Console.WriteLine( ); } } { { services.AddTransient<IServiceA, ServiceA>(); ... } } public interface IServiceA class ServiceA IServiceA "New SA" public class Startup ( ) public void ConfigureServices IServiceCollection services It will raise an exception: System.AggregateException: 'Some services are not able to be constructed' A suitable constructor for type 'AspNetCore.Services.ServiceA' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor. As mentioned in , constructor injection requires a public constructor. ASP.NET Core doc Why public constructor? Because the default accessibility level of constructor is private. DI is implemented by ASP.NET Core, it cannot access other levels except public. Why not public class? Because the DI already gets the class by method call. If we want to access a class by using namespace, public is needed. framework Life Cycle When the following app is running without any request coming, will the singleton service be initialized? { } : { { Console.WriteLine( ); } } { { services.AddSingleton<IServiceA, ServiceA>(); ... } } : { { Console.WriteLine( ); } } public interface IServiceA public class ServiceA IServiceA ( ) public ServiceA "New SA" public class Startup ( ) public void ConfigureServices IServiceCollection services public class HelloController ControllerBase ( ) public WeatherForecastController IServiceA sa $"Test Controller: " {sa.GetHashCode()} The ServiceA won't be initialized. The DI ,m will check the constructor (I guess), but won't initialize the instance. It is only when the singleton service is used that it will be initialized. framework In this case, the service is depended by the controller, and the controller will be initialized for every request. So, as a singleton service, the ServiceA will be initialized when the first request comes. When other requests come after the first request, the singleton service won't be initialized any more: // 1st request New SA Test Controller: 83452835 // 2nd request Test Controller: 83452835 // 3rd request Test Controller: 83452835 If we use `AddScoped` instead of `AddSingleton`, the DI framework will initialize a new instance for every request. // 1st request New SA Test Controller: 72334852 // 2nd request New SA Test Controller: 83729442 // 3rd request New SA Test Controller: 19231424 Initialization Order If we inject dependencies in order of A-B, and fetch them in order of B-A, which one will be initialized first? { } : { { Console.WriteLine( ); } } { } : { { Console.WriteLine( ); } } { { services.AddSingleton<IServiceA, ServiceA>(); services.AddSingleton<IServiceB, ServiceB>(); ... } } : { { Console.WriteLine( ); } } public interface IServiceA public class ServiceA IServiceA ( ) public ServiceA "New SA" public interface IServiceB public class ServiceB IServiceB ( ) public ServiceB "New SB" public class Startup ( ) public void ConfigureServices IServiceCollection services public class HelloController ControllerBase ( ) public WeatherForecastController IServiceB sb, IServiceA sa $"Test Controller: " {sa.GetHashCode()} Result: New SB New SA Test Controller: 83427434 22834295 Although the injection order is A-B, but B will be first initialized because we fetch B first. What if B depends on A? : { { Console.WriteLine( ); } } public class ServiceB IServiceB ( ) public ServiceB IServiceA sa $"New SB with sa: " {sa.GetHashCode()} Result: New SA New SB with sa: Test Controller: 46284926 46284926 64753745 ServiceA will be initialized first, then ServiceB. Given ServiceA is singleton, it will not be initialized again. What if we inject B before A, but B depends on A? { services.AddScoped<IServiceB, ServiceB>(); services.AddScoped<IServiceA, ServiceA>(); } ( ) public void ConfigureServices IServiceCollection services Result: New SA New SB with sa: Test Controller: 72362183 72362183 91218567 The order of injection doesn't matter. The DI container will keep the relationship between the interface and the implement class, and will properly handle everything for us at initialization time. One Interface & Multiple Implement If there are multiple implement class and they are all injected, which one will be initialized? { } : { { Console.WriteLine( ); } } : { { Console.WriteLine( ); } } { { services.AddSingleton<IServiceA, ServiceA>(); services.AddSingleton<IServiceA, ServiceB>(); ... } } : { { Console.WriteLine( ); } } public interface IServiceA public class ServiceA IServiceA ( ) public ServiceA "New SA" public class ServiceB IServiceA ( ) public ServiceB "New SB" public class Startup ( ) public void ConfigureServices IServiceCollection services public class HelloController ControllerBase ( ) public WeatherForecastController IServiceA sa $"Test Controller: " {sa.GetHashCode()} Result: New SB Test Controller: 46399782 Only the last one will be initialized. If you want the first one, use TryAdd. TryAdd won't work if there already exists a registration for the given service interface. Multiple Interface & One Implement If there is multiple interfaces and only one implement class registered as singleton, how many times will it be initialized? { } { } : , { { Console.WriteLine( ); } } { { services.AddSingleton<IServiceA, ServiceB>(); services.AddSingleton<IServiceB, ServiceB>(); ... } } : { { Console.WriteLine( ); } } public interface IServiceA public interface IServiceB public class ServiceB IServiceA IServiceB ( ) public ServiceB "New SB" public class Startup ( ) public void ConfigureServices IServiceCollection services public class HelloController ControllerBase ( ) public WeatherForecastController IServiceA sa, IServiceB sb $"Test Controller: " {sa.GetHashCode()} {sb.GetHashCode()} Result: New SB New SB Test Controller: 78346274 As you see, the singleton in `AddSingleton` refers to the interface not the implement. ServicesB is the implement class of two interfaces, they will be initialized separately. Follow Up All these exercises are very basic and common. Some parts are just my personal opinion. I am a ASP.NET Core beginner, please correct my if you think anything is wrong. If you want to learn more about DI in ASP.NET Core, is a good reading. source code of Microsoft.Extensions.DependencyInjection References Microsoft.Extensions.DependencyInjection Source Code Dependency Injection | ASP.NET Core Docs Understanding Dependency Injection in .NET Core ASP.NET Core Dependency Injection Deep Dive ASP.NET Core Dependency Injection .Net Core Dependency Injection How to use dependency injection in ASP.Net Core