Skip to main content

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.