Exercise 2: DI Service Lifetimes
Objective
Understand Transient, Scoped, and Singleton service lifetimes through practical examples.
Implementation
1. Create Services
public interface IOperationService
{
Guid OperationId { get; }
}
public class TransientService : IOperationService
{
public Guid OperationId { get; } = Guid.NewGuid();
}
public class ScopedService : IOperationService
{
public Guid OperationId { get; } = Guid.NewGuid();
}
public class SingletonService : IOperationService
{
public Guid OperationId { get; } = Guid.NewGuid();
}
2. Register Services
builder.Services.AddTransient<TransientService>();
builder.Services.AddScoped<ScopedService>();
builder.Services.AddSingleton<SingletonService>();
3. Create Test Endpoint
app.MapGet("/lifetimes", (
TransientService transient1,
TransientService transient2,
ScopedService scoped1,
ScopedService scoped2,
SingletonService singleton1,
SingletonService singleton2) =>
{
return new
{
Transient = new
{
Instance1 = transient1.OperationId,
Instance2 = transient2.OperationId,
AreSame = transient1.OperationId == transient2.OperationId
},
Scoped = new
{
Instance1 = scoped1.OperationId,
Instance2 = scoped2.OperationId,
AreSame = scoped1.OperationId == scoped2.OperationId
},
Singleton = new
{
Instance1 = singleton1.OperationId,
Instance2 = singleton2.OperationId,
AreSame = singleton1.OperationId == singleton2.OperationId
}
};
});
4. Test Multiple Requests
# Request 1
curl http://localhost:5000/lifetimes
# Request 2 (compare IDs)
curl http://localhost:5000/lifetimes
Expected Results
- Transient: Different IDs every time (false, false)
- Scoped: Same IDs within request, different across requests (true, false)
- Singleton: Always same IDs (true, true)
Challenge
Create a captive dependency scenario and demonstrate the problem.