C# Academy · Lección

Fundamentos de los contenedores DI

Comprenda la inversión de control, el registro de servicios y cómo el contenedor DI de .NET resuelve las dependencias.

Lección 1 de 413 pasos

Fundamentos de los contenedores DI es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

¿Qué es la inyección de dependencias?

La inyección de dependencias (DI) es un patrón de diseño en el que una clase recibe sus dependencias de una fuente externa en lugar de crearlas por sí misma.

En lugar de escribir var repo = new UserRepository(); dentro de una clase, la clase declara lo que necesita y el contenedor de DI se lo proporciona.

Inversión de control

La DI es una implementación concreta del principio de inversión de control (IoC): el control de la creación de dependencias se transfiere de la clase dependiente a un contenedor externo.

Esto facilita probar y reemplazar las clases.

Configurar el contenedor de DI de .NET

En una aplicación .NET, el contenedor de DI se configura mediante IServiceCollection en Program.cs. Los servicios se registran y, posteriormente, el entorno de ejecución los resuelve.

var builder = WebApplication.CreateBuilder(args);

// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();

var app = builder.Build();
app.Run();

Definir una interfaz y su implementación

La DI funciona mejor cuando se programa contra interfaces. Defina una interfaz para el contrato del servicio y una clase concreta que la implemente.

public interface IUserRepository
{
    User? GetById(int id);
}

public class UserRepository : IUserRepository
{
    public User? GetById(int id)
    {
        // fetch from database
        return new User { Id = id, Name = "Alice" };
    }
}

Resolver servicios mediante el constructor

El contenedor inyecta automáticamente los servicios registrados en los constructores. La clase solo debe declarar la interfaz que necesita; no hace falta usar la palabra clave new.

public class UserService
{
    private readonly IUserRepository _repo;

    public UserService(IUserRepository repo)
    {
        _repo = repo;
    }

    public User? FindUser(int id) => _repo.GetById(id);
}

Registrar varios servicios

Puede registrar tantos servicios como necesite. Los métodos de extensión habituales son AddTransient, AddScoped y AddSingleton; cada uno define un ciclo de vida diferente.

builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();

Usar IServiceProvider directamente

En casos excepcionales, necesitará resolver servicios de forma imperativa. IServiceProvider permite llamar a GetRequiredService<T>() para resolver un servicio, pero en la mayoría de los casos es preferible la inyección mediante constructor.

// Anti-pattern (service locator) — use sparingly
public class ManualResolver
{
    private readonly IServiceProvider _sp;

    public ManualResolver(IServiceProvider sp) => _sp = sp;

    public void DoWork()
    {
        var svc = _sp.GetRequiredService<UserService>();
        svc.FindUser(1);
    }
}

Registrar genéricos abiertos

La DI de .NET admite registros de genéricos abiertos. Puede registrar IRepository<> una sola vez y se resolverá como Repository<T> para cualquier tipo de entidad.

builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>

Validación al iniciar

Con ValidateOnStart() o ValidateScopes = true, el contenedor puede detectar registros mal configurados —por ejemplo, cuando se captura un servicio Scoped dentro de un Singleton— al iniciar la aplicación, en lugar de hacerlo durante la ejecución.

builder.Services.AddScoped<IMyService, MyService>();

// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
    options.ValidateScopes = true;
    options.ValidateOnBuild = true;
});

Decorar servicios

Puede envolver un servicio con un decorador sin modificar la clase original. Registre primero el servicio interno y después el decorador que lo envuelve.

builder.Services.AddScoped<IUserRepository, UserRepository>();

// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet package

En la práctica: Minimal API con DI

En una Minimal API, los servicios se inyectan directamente en los parámetros del controlador de rutas. El contenedor los resuelve automáticamente.

app.MapGet("/users/{id}", (int id, UserService svc) =>
{
    var user = svc.FindUser(id);
    return user is null ? Results.NotFound() : Results.Ok(user);
});

Comprobación rápida

¿Qué método debería preferir para obtener dependencias en la mayoría de las clases?

Recapitulación: fundamentos del contenedor de DI

Ideas clave:

  • La DI invierte la creación de dependencias: el contenedor construye los objetos, no la propia clase
  • Registre servicios con AddTransient / AddScoped / AddSingleton
  • La inyección mediante constructor es el enfoque estándar y recomendado
  • Los genéricos abiertos, los decoradores y ValidateOnBuild son funciones avanzadas muy potentes
Gratis para empezar

Aprende C# con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
93
Lecciones
346

Preguntas frecuentes

¿La lección «Fundamentos de los contenedores DI» es gratis?

Sí — el texto completo de «Fundamentos de los contenedores DI» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Fundamentos de los contenedores DI»?

Comprenda la inversión de control, el registro de servicios y cómo el contenedor DI de .NET resuelve las dependencias. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Fundamentos de los contenedores DI»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Fundamentos de los contenedores DI
  2. Ciclos de vida de servicios: Transient, Scoped, Singleton
  3. Inyección por constructor e interfaces
  4. Patrones Factory y Options
← Volver a C# Academy