0Pricing
C# Academy · Lezione

Fondamenti dei container DI

Comprenda l'inversione del controllo, la registrazione dei servizi e il modo in cui il container DI di .NET risolve le dipendenze.

Fondamenti dei container DI è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Che cos'è l'iniezione delle dipendenze?

L'iniezione delle dipendenze (DI) è un pattern di progettazione in cui una classe riceve le proprie dipendenze da una fonte esterna invece di crearle autonomamente.

Anziché scrivere var repo = new UserRepository(); all'interno di una classe, la classe dichiara ciò di cui ha bisogno e il container DI glielo fornisce.

Inversione del controllo

La DI è un'implementazione concreta del principio di Inversione del controllo (IoC): il controllo della creazione delle dipendenze viene trasferito dalla classe dipendente a un container esterno.

Questo rende le classi più facili da testare e sostituire.

Configurazione del container DI di .NET

In un'app .NET, il container DI viene configurato tramite IServiceCollection in Program.cs. I servizi vengono registrati e poi risolti dal runtime.

var builder = WebApplication.CreateBuilder(args);

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

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

Definizione di un'interfaccia e di un'implementazione

DI funziona al meglio quando si programma verso le interfacce. Definisca un'interfaccia per il contratto del servizio e una classe concreta che la implementi.

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" };
    }
}

Risoluzione dei servizi tramite il costruttore

Il container inserisce automaticamente nei costruttori i servizi registrati. Alla classe basta dichiarare l'interfaccia di cui ha bisogno: non è necessaria la parola chiave new.

public class UserService
{
    private readonly IUserRepository _repo;

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

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

Registrazione di più servizi

Può registrare tutti i servizi necessari. I metodi di estensione più comuni sono AddTransient, AddScoped e AddSingleton: ciascuno definisce una durata diversa.

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

Uso diretto di IServiceProvider

In rari casi è necessario risolvere i servizi in modo imperativo. IServiceProvider consente di chiamare GetRequiredService<T>() per risolvere un servizio, ma nella maggior parte degli scenari è preferibile l'iniezione tramite costruttore.

// 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);
    }
}

Registrazione dei generics aperti

.NET DI supporta le registrazioni di generics aperti. Può registrare una sola volta IRepository<> e risolverlo come Repository<T> per qualsiasi tipo di entità.

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

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

Convalida all'avvio

Con ValidateOnStart() o ValidateScopes = true, il container può rilevare all'avvio dell'applicazione le registrazioni configurate in modo errato, ad esempio l'acquisizione di un servizio Scoped all'interno di un Singleton, invece di rilevarle durante l'esecuzione.

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

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

Decorazione dei servizi

Può racchiudere un servizio in un decoratore senza modificare la classe originale. Registri prima il servizio interno, quindi registri il decoratore che lo racchiude.

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

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

Caso reale: Minimal API con DI

In una Minimal API, i servizi vengono inseriti direttamente nei parametri del gestore della route. Il container li risolve automaticamente.

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

Verifica rapida

Quale metodo dovrebbe preferire per ottenere le dipendenze nella maggior parte delle classi?

Riepilogo: fondamenti del container DI

Punti chiave:

  • La DI inverte la creazione delle dipendenze: è il container a costruire gli oggetti, non la classe stessa
  • Registri i servizi con AddTransient / AddScoped / AddSingleton
  • L'iniezione tramite costruttore è l'approccio standard e preferibile
  • I generics aperti, i decoratori e ValidateOnBuild sono funzionalità avanzate molto potenti

Domande Frequenti

La lezione «Fondamenti dei container DI» è gratuita?

Sì — il testo completo di «Fondamenti dei container DI» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Fondamenti dei container DI»?

Comprenda l'inversione del controllo, la registrazione dei servizi e il modo in cui il container DI di .NET risolve le dipendenze. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Fondamenti dei container DI»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Fondamenti dei container DI
  2. Durata dei servizi: Transient, Scoped, Singleton
  3. Iniezione tramite costruttore e interfacce
  4. Pattern Factory e Options
← Torna a C# Academy