พื้นฐาน ICommand<T>

By suparat · 08 Oct 2025


โอเคครับ 😎 มาลุย ICommand<Guid> แบบละเอียดยิบใน C# / .NET Core สไตล์ CQRS กัน


1️⃣ พื้นฐาน ICommand<T>

โดยทั่วไปใน CQRS (Command Query Responsibility Segregation) เราจะแบ่งออกเป็น 2 ส่วน:

ส่วน ความหมาย
Query อ่านข้อมูล (Read)
Command เขียน/แก้ไขข้อมูล (Write)

ICommand<T> คือ interface สำหรับ Command ที่ระบุว่า:

“เมื่อรัน Command นี้แล้ว จะคืนค่า T

  • T มักเป็น ผลลัพธ์ของการสร้าง/แก้ไข เช่น Guid ของ entity ที่สร้างใหม่ หรือ bool สำหรับสถานะสำเร็จ/ล้มเหลว


2️⃣ ตัวอย่าง ICommand<Guid>

public interface ICommand<TResult>
{
    // Marker interface หรือใส่ property/metadata ที่จำเป็นสำหรับ Command
}

สมมติเราต้องการสร้าง Log ใหม่:

public class CreateAppLogCommand : ICommand<Guid>
{
    public string Message { get; set; } = string.Empty;
    public string Level { get; set; } = "Info"; // Info, Warning, Error
}
  • ICommand<Guid> → บอกว่า ผลลัพธ์ของการรัน command นี้คือ Guid

  • Guid อาจเป็น ID ของ log ใหม่ ที่ถูกสร้างใน DB


3️⃣ Command Handler: ICommandHandler<TCommand, TResult>

เพื่อทำงานกับ command เราจะใช้ handler:

public interface ICommandHandler<TCommand, TResult>
    where TCommand : ICommand<TResult>
{
    Task<TResult> HandleAsync(TCommand command);
}
  • รับ TCommand → ทำ action → return TResult


4️⃣ ตัวอย่าง Command Handler: สร้าง log

public class CreateAppLogCommandHandler : ICommandHandler<CreateAppLogCommand, Guid>
{
    private readonly AppDbContext _dbContext;

    public CreateAppLogCommandHandler(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<Guid> HandleAsync(CreateAppLogCommand command)
    {
        var entity = new AppLog
        {
            Id = Guid.NewGuid(),
            Message = command.Message,
            Level = command.Level,
            CreatedAt = DateTime.UtcNow
        };

        _dbContext.AppLogs.Add(entity);
        await _dbContext.SaveChangesAsync();

        // คืนค่า ID ของ log ที่สร้างใหม่
        return entity.Id;
    }
}

อธิบายทีละขั้น:

  1. ICommandHandler<CreateAppLogCommand, Guid> → คืนค่า Guid ของ entity ใหม่

  2. HandleAsync → method ทำงานจริงกับ DB

  3. สร้าง entity ใหม่ map จาก command

  4. save ลง DB

  5. return Guid ของ log ใหม่


5️⃣ วิธีเรียกใช้งาน

var command = new CreateAppLogCommand
{
    Message = "Something happened",
    Level = "Error"
};

Guid newLogId = await _commandBus.SendAsync(command);

Console.WriteLine($"New log created with ID: {newLogId}");
  • Command bus / mediator จะส่ง command ไปหา handler ที่ตรงกัน

  • คืนค่า Guid ของ entity ใหม่


6️⃣ สรุป Concept

สิ่งที่ทำ ความหมาย
ICommand<Guid> Command ที่เมื่อรันแล้วคืนค่า Guid
CreateAppLogCommand Command สำหรับสร้าง log ใหม่
CreateAppLogCommandHandler Handler ทำงานจริงกับ DB
HandleAsync สร้าง entity, save DB, return Guid
CQRS Pattern แยก Read / Write → maintainable, testable

💡 Tip:

  • ถ้า command ไม่ต้อง return อะไร → ใช้ ICommand<Unit> หรือ Task

  • Command handler ไม่ควร query หรือ return ข้อมูลอื่น ๆ มากเกินไป → ทำงานแค่ write / mutate


ถ้าคุณอยาก ผมสามารถ วาด diagram flowของ ICommand ตั้งแต่ Controller → Command → Handler → DB → return Guid ให้เห็นภาพชัด ๆ แบบ step by step ให้เลยครับ

คุณอยากให้ผมวาด diagram ให้ไหม?

พื้นฐาน ICommand<T>
Web hosting by Somee.com