La gestión del ciclo de vida de las dependencias es la organización de la creación, inicialización, actualización y destrucción de los componentes de la aplicación de tal manera que sean independientes entre sí y fáciles de probar. Para ello, se utilizan a menudo contenedores IoC (Inversión de Control) y el patrón de Inyección de Dependencias (DI).
Contenedor IoC permite:
Ejemplo en C# usando Microsoft.Extensions.DependencyInjection:
public interface IMessageSender { void Send(string msg); } public class EmailSender : IMessageSender { public void Send(string msg) { /* enviar email */ } } // Registro de dependencias var services = new ServiceCollection(); services.AddScoped<IMessageSender, EmailSender>(); // Obtener una instancia var provider = services.BuildServiceProvider(); var sender = provider.GetService<IMessageSender>(); sender.Send("¡Hola!");
Características clave:
¿Cuál es la diferencia entre la inyección de dependencias (DI) y el patrón Service Locator, y por qué se considera que el Service Locator es un antipatrón?
El Service Locator rompe la transferencia explícita de dependencias, haciendo que el código sea menos transparente. Es mejor usar DI a través del constructor o métodos para que el compilador controle la corrección de las dependencias.
// Malo: Service Locator var sender = ServiceLocator.Get<IMessageSender>(); // Bueno: a través de DI public class MyService { public MyService(IMessageSender sender) { ... } }
¿Cuál es la diferencia entre el patrón Singleton y el tiempo de vida de Single Instance en el contenedor DI?
El patrón Singleton se implementa manualmente y no depende del contenedor; el Single Instance proporciona una instancia del contenedor, lo cual es más seguro para las pruebas unitarias y la extensión.
¿Es necesario inyectar dependencias en todas las clases, incluso en utilidades simples?
No. No tiene sentido inyectar DI en utilidades sin dependencias o clases helper débilmente acopladas (por ejemplo, clase de constantes matemáticas) — esto complica el código sin aportar beneficios.