Contenedor de Dependency Injection para C# (.NET) — guía completa

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

Contenedor de Dependency Injection para C# (.NET): guía completa



Dependency Injection (DI) es uno de los principios clave del desarrollo moderno en C# (.NET) que permite crear aplicaciones débilmente acopladas, comprobables y fáciles de mantener. En el ecosistema .NET, la herramienta principal para implementar DI es el contenedor integrado del paquete Microsoft.Extensions.DependencyInjection. En este artículo, analizaremos en detalle qué es un contenedor DI, cómo configurarlo, qué ciclos de vida existen y cómo usarlo correctamente en proyectos reales.



¿Qué es un contenedor de Dependency Injection?



Un contenedor de Dependency Injection (o contenedor IoC) es un componente de software que gestiona automáticamente la creación e inyección de dependencias de objetos. En lugar de crear objetos manualmente con new, registra los tipos en el contenedor, y este se encarga de crearlos y vincularlos.



Principales ventajas de usar un contenedor DI:

  • Reducción del acoplamiento del código — las clases dependen de abstracciones (interfaces), no de implementaciones concretas.
  • Simplificación de las pruebas — es fácil reemplazar dependencias con objetos mock.
  • Gestión centralizada del ciclo de vida — controla cuándo se crean y destruyen los objetos.
  • Mayor flexibilidad — se pueden cambiar las implementaciones sin modificar el código de los consumidores.


Instalación y configuración del contenedor DI



En los proyectos .NET modernos (ASP.NET Core, Console, Worker Services), el contenedor DI ya está integrado. Para usarlo, solo necesita agregar el paquete al proyecto:



dotnet add package Microsoft.Extensions.DependencyInjection


Después de esto, se crea una instancia de IServiceCollection en la que se registran todas las dependencias. Veamos un ejemplo simple de registro de servicios:



using Microsoft.Extensions.DependencyInjection;

// Definimos la interfaz y su implementaciónpublic interface IMessageService{ void Send(string message);}

public class EmailService : IMessageService{ public void Send(string message) { Console.WriteLine($"Email sent: {message}"); }}

// Configuración del contenedorvar services = new ServiceCollection();services.AddTransient<IMessageService, EmailService>();

// Construimos el proveedor de serviciosvar serviceProvider = services.BuildServiceProvider();

// Obtenemos una instancia del serviciovar messageService = serviceProvider.GetService<IMessageService>();messageService.Send("Hello from DI!");


Ciclos de vida de las dependencias



El contenedor DI admite tres modos principales de gestión del tiempo de vida de los objetos:



  • Transient (AddTransient) — cada solicitud crea una nueva instancia. Adecuado para servicios ligeros sin estado.
  • Scoped (AddScoped) — una instancia por ámbito (por ejemplo, por solicitud HTTP en ASP.NET Core). Ideal para servicios con estado dentro de una sola operación.
  • Singleton (AddSingleton) — una única instancia para toda la aplicación. Se utiliza para cachés, registradores, configuraciones.


Ejemplo de registro con diferentes ciclos de vida:



services.AddTransient<ITransientService, TransientService>();services.AddScoped<IScopedService, ScopedService>();services.AddSingleton<ISingletonService, SingletonService>();


Importante: si un servicio depende de otro servicio con un ciclo de vida más corto, esto puede provocar errores (por ejemplo, un Singleton que usa un Scoped). Estas situaciones se denominan "captive dependencies" y deben evitarse.



Inyección de dependencias a través del constructor



La forma más común de inyección es a través del constructor. El contenedor resuelve automáticamente todas las dependencias

Recommendations