Dependency Injection (DI) is a design pattern used in software development to achieve loose coupling between objects and their dependencies. In simple terms, it allows you to inject dependencies (services, objects, or classes) into a class, rather than having the class create or manage those dependencies itself. This makes the code more flexible, testable, and easier to maintain.
This improves modularity, testability, and maintainability of code by reducing tight coupling between classes.
In simpler terms, Dependency Injection allows an object to receive its dependencies from the outside world, making the class easier to manage and test.
Key Concepts of Dependency Injection
Dependency:
A dependency is an object or service that a class needs to function. For example, if a Car class relies on an Engine class to operate, the Engine is a dependency of the Car.
Injection:
The process of supplying the dependencies to a class from an external source is called "injection." Instead of a class creating its dependencies, they are "injected" into the class, usually via constructors, properties, or methods.
Types of Dependency Injection
There are three main types of dependency injection:
Constructor Injection:
Dependencies are provided to a class through its constructor. This is the most common and preferred method in many frameworks.
Example:
public class Car
{
private readonly IEngine _engine;
// Constructor injection
public Car(IEngine engine)
{
_engine = engine;
}
public void Drive()
{
_engine.Start();
Console.WriteLine("Car is driving...");
}
}
Property Injection (Setter Injection):
Dependencies are provided through property setters after the object is created.
Example:
public class Car
{
public IEngine Engine { get; set; }
public void Drive()
{
Engine.Start();
Console.WriteLine("Car is driving...");
}
}
Method Injection:
Dependencies are passed directly to a method as parameters, allowing for fine-grained control over the lifecycle of the dependency.
Example:
public class Car
{
public void Drive(IEngine engine)
{
engine.Start();
Console.WriteLine("Car is driving...");
}
}
Benefits of Dependency Injection
Loose Coupling:
Improved Testability:
Flexibility:
Maintainability:
Real-Life Example of Dependency Injection in WPF Application Using Prism Framework
Step 1: Setting Up Prism and Unity
Step 2: Define a Service Interface and Implementation
public interface ILoggerService{void Log(string message);}
public class LoggerService : ILoggerService{public void Log(string message){// Log message to console for simplicityConsole.WriteLine($"Log: {message}");}}
Step 3: Creating the ViewModel
using Prism.Mvvm;public class MainWindowViewModel : BindableBase{private readonly ILoggerService _logger;public MainWindowViewModel(ILoggerService loggerService){_logger = loggerService;_logger.Log("MainWindowViewModel initialized.");}}
Step 4: Configuring the Unity Container in App.xaml.cs
using Prism.Ioc;using Prism.Unity;using System.Windows;namespace DependencyInjectionExample{public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){// Register the ILoggerService to be injected wherever needed
containerRegistry.Register<ILoggerService, LoggerService>();}}}
Step 5: Using the ViewModel in MainWindow
<Window x:Class="DependencyInjectionExample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Dependency Injection Example" Height="200" Width="400"><Grid><TextBlock Text="Check Console for Log Output" HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></Window>
0 Comments