Dependency Injection (DI) is a design pattern in which an object receives its dependencies from external sources rather than creating them itself. This pattern promotes loose coupling between components and increases testability.
In .NET Core, DI is built-in, making it easy to implement. It allows you to register services (interfaces and their implementations) with a built-in IoC (Inversion of Control) container, and the container automatically injects the services where needed.
How Dependency Injection Works in .NET Core
Service Registration: You register the services (interfaces and their implementations) in the Startup.cs file in the ConfigureServices method.
Service Resolution: The framework resolves dependencies and injects them into constructors, methods, or properties where needed.
Service Lifetime: .NET Core provides three main lifetimes for services:
Transient: A new instance is created every time the service is requested.
Scoped: A new instance is created per request (or per scope).
Singleton: A single instance is created and shared throughout the application lifetime.
Example of Setting Up Dependency Injection in a .NET Core Application
Here’s a simple example demonstrating how to set up DI in a .NET Core application.
1. Define a Service Interface and Its Implementation
2. Register the Service in Startup.cs
In .NET Core, you register services in the ConfigureServices method inside Startup.cs
3. Inject the Service in a Controller
Once the service is registered, you can inject it into a controller or any other class by simply adding it to the constructor.
4. Use the Service in the View
Service Lifetimes in DI
Transient (AddTransient<TService, TImplementation>()): A new instance of the service is created each time it is requested.
Scoped (AddScoped<TService, TImplementation>()): A new instance is created once per request.
Singleton (AddSingleton<TService, TImplementation>()): A single instance is shared across the entire application.
Benefits of Using DI
Loose Coupling: Classes are decoupled from the concrete implementations of their dependencies.
Testability: Dependencies can be mocked or replaced for testing.
Maintainability: Centralized service configuration makes it easier to manage dependencies.