Attendance App: Real-Time Use of DI Lifetimes
Attendance App: Real-Time Use of DI Lifetimes
App Features:
- Students
check-in/out
- Admin
manages students
- Log
every operation (via Singleton)
- Attendance
processed per request (Scoped)
- Utility
services like OTP, Email (Transient)
1. Service
Lifetimes in Real Context
Service |
Lifetime |
Why? |
ILoggingService |
Singleton |
One instance, logs everything app-wide |
AttendanceService |
Scoped |
Scoped per HTTP request (to avoid stale
state) |
EmailNotificationService |
Transient |
Lightweight utility, recreated each time |
OtpGeneratorService |
Transient |
Stateless, new per use |
DbContext (EF Core) |
Scoped |
Scoped per request to manage transactions
safely |
2. Interface
Definitions
public interface
ILoggingService
{
void Log(string message);
}
public interface
IAttendanceService
{
string MarkAttendance(int studentId);
}
public interface
IEmailNotificationService
{
void Send(string to, string subject, string
body);
}
public interface
IOtpGeneratorService
{
string GenerateOtp();
}
3.
Implementations
public class
LoggingService : ILoggingService
{
private readonly string _id =
Guid.NewGuid().ToString();
public void Log(string message)
{
Console.WriteLine($"[{_id}]
{DateTime.Now}: {message}");
}
}
public class
AttendanceService : IAttendanceService
{
private readonly ILoggingService _logger;
public AttendanceService(ILoggingService
logger)
{
_logger = logger;
}
public string MarkAttendance(int studentId)
{
_logger.Log($"Attendance marked
for student ID: {studentId}");
return $"Attendance marked for
student {studentId}";
}
}
public class
EmailNotificationService : IEmailNotificationService
{
private readonly ILoggingService _logger;
public
EmailNotificationService(ILoggingService logger)
{
_logger = logger;
}
public void Send(string to, string subject,
string body)
{
_logger.Log($"Email sent to {to}
with subject '{subject}'");
}
}
public class
OtpGeneratorService : IOtpGeneratorService
{
public string GenerateOtp()
{
return new Random().Next(100000,
999999).ToString();
}
}
4. Register
Services in Program.cs
builder.Services.AddSingleton<ILoggingService,
LoggingService>(); //
Singleton
builder.Services.AddScoped<IAttendanceService,
AttendanceService>(); // Scoped
builder.Services.AddTransient<IEmailNotificationService,
EmailNotificationService>(); // Transient
builder.Services.AddTransient<IOtpGeneratorService,
OtpGeneratorService>(); // Transient
5. Controller
Example
[ApiController]
[Route("api/[controller]")]
public class
AttendanceController : ControllerBase
{
private readonly IAttendanceService
_attendanceService;
private readonly IEmailNotificationService
_emailService;
private readonly IOtpGeneratorService
_otpService;
private readonly ILoggingService _logger;
public AttendanceController(
IAttendanceService attendanceService,
IEmailNotificationService emailService,
IOtpGeneratorService otpService,
ILoggingService logger)
{
_attendanceService = attendanceService;
_emailService = emailService;
_otpService = otpService;
_logger = logger;
}
[HttpPost("{studentId}")]
public IActionResult MarkAttendance(int
studentId)
{
var attendanceResult = _attendanceService.MarkAttendance(studentId);
string otp = _otpService.GenerateOtp();
_emailService.Send("student@school.com", "Attendance
Marked", $"Your OTP: {otp}");
_logger.Log("Attendance workflow
completed.");
return Ok(new
{
Attendance = attendanceResult,
OtpSent = otp
});
}
}
Final Output
Example (when you hit /api/Attendance/101):
{
"Attendance": "Attendance
marked for student 101",
"OtpSent": "732819"
}
Summary of
Real-Time DI Use:
Service |
Real Usage |
Lifetime Reason |
ILoggingService |
Log across layers |
Singleton = one instance/log |
AttendanceService |
Track each request |
Scoped = avoids state leakage |
EmailNotificationService |
Email per student on attendance mark |
Transient = light, throwaway |
OtpGeneratorService |
New OTP per use |
Transient = stateless |
Comments
Post a Comment