Dependency Injection

Dependency Injection (DI) is a design pattern used to implement IoC (Inversion of Control). It allows for the creation of dependent objects outside of a class and provides those objects to a class through different ways. It's a technique to achieve loose coupling between classes and their dependencies.

  1. Maintainability: Makes your code more modular and easier to maintain.

  2. Testability: Simplifies unit testing by allowing mock dependencies.

  3. Reusability: Encourages reusability of code by decoupling components.

  4. Flexibility: Makes it easier to swap implementations without changing the dependent class.

  5. Readability: Enhances code readability and structure by clearly defining dependencies.

Common Use Cases of DI

  1. Service Lifetimes: Managing object lifetimes, like Singleton, Scoped, and Transient, to optimize resource usage.

  2. Testing: Creating mock implementations of dependencies for unit tests.

  3. Configuration: Injecting configuration settings and options into services.

Service Lifetimes: Singleton, Scoped, Transient

  1. Singleton

    • Definition: A single instance is created for the lifetime of the application.

    • Use For: Services that need to maintain state across requests, like configuration settings or shared data.

    • Analogy: Imagine you have one water bottle. Everyone drinks from this same bottle. If too many people try to drink at the same time (concurrency), it might become a mess.

    • Example: Shared configuration service.

    • ASP.NET Core Registration:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddSingleton<IMyService, MyService>();
      }
  2. Scoped

    • Definition: A new instance is created per scope, typically per web request.

    • Use For: Services that should be unique to a single request but reused within that request, like database contexts.

    • Analogy: Imagine you can enter a room and move every object around. When you exit and re-enter, all objects are reset to their original positions.

    • Example: Database context in a web application.

    • ASP.NET Core Registration:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddScoped<IMyService, MyService>();
      }
  3. Transient

    • Definition: A new instance is created each time the service is requested.

    • Use For: Lightweight, stateless services that do not need to maintain state.

    • Analogy: You get a new water bottle every time you ask for one. It's independent, and there's no conflict with others.

    • Example: Utility or helper services.

    • ASP.NET Core Registration:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddTransient<IMyService, MyService>();
      }

Dependency Injection in ASP.NET Core

In ASP.NET Core, DI is a built-in feature, making it simple to use without additional libraries.

Example Service Implementation

Program.cs

MyService.cs

Dependency Injection in Console Applications

While DI is commonly associated with web applications, it can also be used in console applications.

Example in Console Application:

  1. Setup DI Container

Create a ServiceCollection and configure your services.

Program.cs

Conclusion

Dependency Injection is a fundamental pattern for modern software development, promoting better code structure, testability, and maintainability. By understanding and using different lifetimes (Singleton, Scoped, Transient), you can optimize resource management in your applications, whether in ASP.NET Core or even console applications.

Last updated