พฤติกรรมของไปป์ไลน์
เพิ่มตรรกะที่ใช้ร่วมกันหลายส่วนด้วยพฤติกรรม
พฤติกรรมของไปป์ไลน์ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
ประเด็นข้ามส่วน
การบันทึกล็อก การตรวจสอบความถูกต้อง การจับเวลา และธุรกรรม ล้วนใช้กับ handler หลายรายการ การคัดลอกโค้ดเหล่านี้ไปไว้ใน handler แต่ละตัวเป็นงานซ้ำซากและทำให้เกิดข้อผิดพลาดได้ง่าย
พฤติกรรมไปป์ไลน์ ของ MediatR ช่วยให้คุณครอบทุกคำขอด้วยตรรกะที่ใช้ร่วมกันได้
// One behavior runs around all handlersIPipelineBehavior
พฤติกรรมหนึ่งจะใช้งาน IPipelineBehavior<TRequest, TResponse> เมธอด Handle ของพฤติกรรมจะได้รับคำขอและตัวมอบหมาย next ซึ่งเรียกใช้ส่วนที่เหลือของไปป์ไลน์
public class LoggingBehavior<TRequest, TResponse>
: IPipelineBehavior<TRequest, TResponse>
where TRequest : notnull
{
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
// before
var response = await next();
// after
return response;
}
}ตัวมอบหมายถัดไป
next() จะเรียกใช้พฤติกรรมถัดไป หรือเรียกใช้ handler จริงหากนี่เป็นพฤติกรรมสุดท้าย โค้ดที่อยู่ ก่อน การเรียกจะทำงานขณะคำขอเข้ามา ส่วนโค้ดที่อยู่ หลัง การเรียกจะทำงานขณะคำขอส่งกลับ
// [Behavior A in] -> [Behavior B in] -> [Handler]
// <- [Behavior B out] <- [A out]พฤติกรรมการบันทึกล็อก
พฤติกรรมการบันทึกล็อกที่ใช้งานจริงจะบันทึกชื่อคำขอขณะคำขอเข้ามา และบันทึกเวลาที่ผ่านไปขณะคำขอส่งกลับ
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
var name = typeof(TRequest).Name;
_logger.LogInformation("Handling {Name}", name);
var sw = Stopwatch.StartNew();
var response = await next();
_logger.LogInformation("{Name} took {Ms}ms", name, sw.ElapsedMilliseconds);
return response;
}การลงทะเบียนพฤติกรรม
ลงทะเบียนพฤติกรรมแบบเจเนอริกเปิดใน DI MediatR จะนำพฤติกรรมนี้ไปใช้กับทุกคำขอ
builder.Services.AddTransient(
typeof(IPipelineBehavior<,>),
typeof(LoggingBehavior<,>));พฤติกรรมการตรวจสอบความถูกต้อง
การใช้งานที่ได้รับความนิยมคือการตรวจสอบคำขอด้วย FluentValidation พฤติกรรมนี้จะเรียกใช้ตัวตรวจสอบทั้งหมดก่อนที่ handler จะทำงาน และโยนข้อผิดพลาดหากมีรายการใดไม่ผ่าน
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
var context = new ValidationContext<TRequest>(request);
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(r => r.Errors)
.Where(f => f is not null)
.ToList();
if (failures.Count != 0)
throw new ValidationException(failures);
return await next();
}การตัดการทำงานล่วงหน้า
พฤติกรรมสามารถ ข้ามการทำงานของ handler ทั้งหมด ได้โดยส่งคืนผลลัพธ์โดยไม่เรียก next() ซึ่งมีประโยชน์สำหรับการแคชผลลัพธ์ของคิวรีหรือการปฏิเสธคำขอที่ไม่ถูกต้อง
if (_cache.TryGet(key, out TResponse cached))
return cached; // handler never runs
var response = await next();
_cache.Set(key, response);
return response;การจัดลำดับพฤติกรรม
พฤติกรรมจะทำงานตามลำดับที่ลงทะเบียนไว้ ให้การบันทึกล็อกอยู่ชั้นนอกสุด ตามด้วยการตรวจสอบความถูกต้อง แล้วจึงเป็นธุรกรรม เพื่อให้แต่ละรายการครอบรายการถัดไปได้อย่างถูกต้อง
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));พฤติกรรมธุรกรรม
ครอบ handler ของคำสั่งไว้ในธุรกรรมฐานข้อมูล เพื่อให้การดำเนินการทั้งหมดถูกยืนยันหรือย้อนกลับแบบเป็นหน่วยเดียวกัน
await using var tx = await _db.Database.BeginTransactionAsync(ct);
try
{
var response = await next();
await tx.CommitAsync(ct);
return response;
}
catch
{
await tx.RollbackAsync(ct);
throw;
}การกำหนดเป้าหมายให้คำขอบางรายการ
ใช้อินเทอร์เฟซเครื่องหมายและข้อจำกัดแบบเจเนอริก เพื่อให้พฤติกรรมมีผลเฉพาะกับคำขอที่เลือกใช้เท่านั้น เช่น ให้ธุรกรรมมีผลเฉพาะกับคำสั่ง
public interface ITransactional { }
public record CreateOrderCommand(...) : IRequest<int>, ITransactional;
// where TRequest : ITransactionalเหตุใดพฤติกรรมจึงดีกว่ามิดเดิลแวร์
พฤติกรรมต่างจากมิดเดิลแวร์ HTTP ตรงที่ทำงานแบบ per ข้อความ มีคำขอและการตอบกลับที่ระบุชนิดข้อมูล และยังทำงานได้แม้คำขอจะถูกส่งออกนอก HTTP เช่น จากงานเบื้องหลัง
// Strongly typed, transport-independent cross-cutting logicตรวจสอบความเข้าใจอย่างรวดเร็ว
ยืนยันวิธีการทำงานของพฤติกรรม
สรุป
คุณได้เรียนรู้พฤติกรรมไปป์ไลน์ดังนี้:
IPipelineBehavior<TRequest, TResponse>ครอบทุกคำขอด้วยตรรกะที่ใช้ร่วมกัน- ตัวมอบหมาย
nextเลื่อนไปยังขั้นถัดไปของไปป์ไลน์ การข้ามตัวมอบหมายนี้จะตัดการทำงานของ handler ล่วงหน้า - การใช้งานทั่วไป ได้แก่ การบันทึกล็อก การตรวจสอบความถูกต้อง ธุรกรรม และการแคช
- พฤติกรรมทำงานตามลำดับการลงทะเบียนและมีการระบุชนิดข้อมูลอย่างเคร่งครัด
ถัดไป: การแจ้งเตือนและเหตุการณ์
คำถามที่พบบ่อย
บทเรียน “พฤติกรรมของไปป์ไลน์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “พฤติกรรมของไปป์ไลน์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “พฤติกรรมของไปป์ไลน์”
เพิ่มตรรกะที่ใช้ร่วมกันหลายส่วนด้วยพฤติกรรม คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “พฤติกรรมของไปป์ไลน์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนวคิด CQRS
- คำสั่งและตัวจัดการด้วย MediatR
- พฤติกรรมของไปป์ไลน์
- การแจ้งเตือนและเหตุการณ์