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.
Maintainability: Makes your code more modular and easier to maintain.
Testability: Simplifies unit testing by allowing mock dependencies.
Reusability: Encourages reusability of code by decoupling components.
Flexibility: Makes it easier to swap implementations without changing the dependent class.
Readability: Enhances code readability and structure by clearly defining dependencies.
Common Use Cases of DI
Service Lifetimes: Managing object lifetimes, like Singleton, Scoped, and Transient, to optimize resource usage.
Testing: Creating mock implementations of dependencies for unit tests.
Configuration: Injecting configuration settings and options into services.
Service Lifetimes: Singleton, Scoped, Transient
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.
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:
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.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddSingleton<IMyService, MySingletonService>();
services.AddScoped<IMyService, MyScopedService>();
services.AddTransient<IMyService, MyTransientService>();
});
}
public interface IMyService
{
void DoWork();
}
public class MySingletonService : IMyService
{
public void DoWork()
{
Console.WriteLine("Singleton Service Work Done!");
}
}
public class MyScopedService : IMyService
{
public void DoWork()
{
Console.WriteLine("Scoped Service Work Done!");
}
}
public class MyTransientService : IMyService
{
public void DoWork()
{
Console.WriteLine("Transient Service Work Done!");
}
}
using Microsoft.Extensions.DependencyInjection;
using System;
public interface IMyService
{
void DoWork();
}
public class MyService : IMyService
{
public void DoWork()
{
Console.WriteLine("Work done!");
}
}
public class Program
{
static void Main(string[] args)
{
// Setup DI
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// Create ServiceProvider
var serviceProvider = serviceCollection.BuildServiceProvider();
// Resolve service
var myService = serviceProvider.GetService<IMyService>();
myService.DoWork();
}
private static void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IMyService, MyService>();
}
}