Inyección de Dependencias en C#: guía práctica con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: qué es la Inyección de Dependencias y por qué es necesaria

La Inyección de Dependencias (DI) es uno de los patrones de diseño clave que implementa el principio de inversión de dependencias (Dependency Inversion Principle) de SOLID. En la práctica, esto significa que los objetos no crean sus dependencias por sí mismos, sino que las reciben desde el exterior. Esto hace que el código sea flexible, comprobable y débilmente acoplado.

En el ecosistema de C# y .NET, DI se ha convertido en el estándar de facto. Desde .NET Core, la plataforma incluye su propio contenedor de inyección de dependencias, que se utiliza en ASP.NET Core, servicios en segundo plano e incluso en aplicaciones de consola. Sin comprender DI, es imposible imaginar el desarrollo moderno en C#.

En este artículo, analizaremos DI con ejemplos reales: desde la inyección manual hasta el uso del contenedor integrado de .NET. Verá cómo eliminar los acoplamientos rígidos y hacer que el código sea adecuado para pruebas unitarias.



El problema sin Inyección de Dependencias

Imaginemos un escenario típico: la clase OrderService procesa pedidos y envía notificaciones por correo electrónico. Sin DI, el código se ve así:

public class EmailSender{    public void Send(string to, string subject, string body)    {        Console.WriteLine($"Enviando correo a {to}: {subject}");    }}

public class OrderService{ private EmailSender _emailSender;

public OrderService() { // Acoplamiento rígido: la clase crea su propia dependencia _emailSender = new EmailSender(); }

public void ProcessOrder(int orderId) { // Lógica de procesamiento del pedido... _emailSender.Send("user@example.com", "Pedido confirmado", $"Su pedido #{orderId} ha sido recibido."); }}

¿Cuál es el problema? OrderService está rígidamente vinculado a la implementación concreta de EmailSender. Si queremos reemplazar el envío de correos electrónicos por SMS o registro en bitácora, tendríamos que modificar el código de OrderService. Las pruebas también se complican: no es posible sustituir el EmailSender real por un objeto mock.



Solución: inyección de dependencias por constructor

El primer paso hacia DI es extraer una abstracción (interfaz) y pasar la dependencia a través del constructor. Esto se llama Inyección por Constructor (Constructor Injection).



Paso 1: Crear la interfaz

public interface INotificationService{    void Send(string to, string subject, string body);}


Paso 2: Implementar la interfaz

public class EmailSender : INotificationService{    public void Send(string to, string subject, string body)    {        Console.WriteLine($"Correo enviado: {subject} -> {to}");    }}

public class SmsSender : INotificationService{ public void Send(string to, string subject, string body) { Console.WriteLine($"SMS enviado: {subject} -> {to}"); }}


Paso 3: Inyectar la dependencia por constructor

public class OrderService{    private readonly INotificationService _notificationService;

// La dependencia se pasa desde el exterior public OrderService(INotificationService notificationService) { _notificationService = notificationService; }

public void ProcessOrder(int orderId) { // Lógica de procesamiento del pedido... _notificationService.Send("user@example.com", "Pedido confirmado", $"Su pedido #{orderId} ha sido recibido."); }}

Ahora OrderService no sabe qué implementación concreta se está utilizando. Podemos usar EmailSender, SmsSender o cualquier otra clase que implemente INotificationService. El código se ha vuelto flexible y comprobable.



Uso del contenedor IoC integrado en .NET

Crear todas las dependencias manualmente es incómodo. .NET tiene un contenedor integrado (contenedor IoC) que gestiona automáticamente el ciclo de vida de los objetos. Veamos un ejemplo para una aplicación de consola.



Paso 1: Instalar el paquete

Blogs

Book Recommendations