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

Popular posts from this blog

Promises in Angular

Mastering Your Angular Workflow: Essential CLI Commands for Efficient Development

Observables in Angular