Dependency Injection in Simple Terms with ASP.NET Core

M.F.M Fazrin
3 min readJan 2, 2023

--

In dependency injection, the lifetime of a service determines how long the service instance is kept in memory and how it is used by the application.

In ASP.NET Core, there are three main lifetime options for registering services:

Transient: A new instance of the service is created each time it is requested. This is useful for lightweight, stateless services.

Here’s an example of how to register a transient service in ASP.NET Core:

services.AddTransient<IMyService, MyService>();

Scope: For each request in a certain scope, a new instance of the service is made. Scopes are typically created by the framework for each HTTP request. This is useful for maintaining state within a request.

Here’s an example of how to register a scoped service in ASP.NET Core:

services.AddScoped<IMyService, MyService>();

Singleton: A single instance of the service is created and shared for all requests. This is useful for maintaining state across the entire application.

Here’s an example of how to register a singleton service in ASP.NET Core:

services.AddSingleton<IMyService, MyService>();

It's critical to select the right lifetime for your services based on their intended use. For example, a service should be registered as a singleton if it is meant to keep state across the whole application. On the other hand, if a service is stateless and lightweight, it may be more appropriate to register it as a transient service.

There are several advantages to using dependency injection:

  1. Improved testability: Dependency injection makes it easier to write unit tests for your code, as you can easily swap out real dependencies with mock dependencies.
  2. Loose coupling: Dependency injection allows you to decouple your classes from their dependencies, which makes it easier to change the implementation of a dependency without affecting the consuming class.
  3. Reusability: Dependency injection allows you to reuse code more easily, as you can easily swap out dependencies with different implementations.
  4. Maintainability: Dependency injection makes it easier to maintain your code, as you can more easily change the implementation of a dependency without affecting the consuming class.
  5. Extensibility: Dependency injection allows you to more easily extend your code, as you can easily swap out dependencies with different implementations.

There are a few potential disadvantages to using dependency injection:

  1. Increased complexity: Dependency injection can make your codebase more complex, as you need to manage the injection of dependencies.
  2. Performance overhead: Dependency injection can introduce a performance overhead, as the framework needs to create and manage the dependencies. This is generally not a significant concern in most applications, but it is something to be aware of.
  3. Difficulty debugging: Dependency injection can make it more difficult to debug your code, as it can be harder to understand the flow of control when dependencies are being injected.
  4. Overuse: Dependency injection can lead to overuse, where every class has many dependencies that are injected, leading to a confusing and hard-to-maintain codebase. It is important to use dependency injection judiciously and only for dependencies that are truly needed.

--

--

M.F.M Fazrin

Senior Software Development Specialist @ Primary Health Care Corporation (Qatar)