0Pricing
C# Academy · درس

الإشعارات والأحداث

انشروا أحداث المجال باستخدام MediatR

الإشعارات والأحداث درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

الطلبات مقابل الإشعارات

للطلب معالج واحد ويُرجع قيمة. أما الإشعار فهو بث: له صفر من المعالجات أو أكثر ولا يُرجع شيئًا. استخدم الإشعارات للإعلان عن حدوث أمر ما.

// Request:      one handler, returns a result
// Notification: many handlers, fire-and-forget

INotification

حدث المجال هو سجل يطبّق INotification. ويصف حقيقةً حدثت في الماضي.

public record OrderPlacedNotification(int OrderId, int CustomerId)
    : INotification;

INotificationHandler

ينفّذ كل مشترك INotificationHandler<TNotification>. ويمكن لعدة معالجات الاشتراك في الإشعار نفسه، بحيث يعالجه كل منها بشكل مستقل.

public class SendConfirmationEmailHandler
    : INotificationHandler<OrderPlacedNotification>
{
    public Task Handle(
        OrderPlacedNotification n, CancellationToken ct)
    {
        // send the email...
        return Task.CompletedTask;
    }
}

مشتركون متعددون

أضف العدد الذي تحتاج إليه من المعالجات. لا يعرف أيٌّ منها شيئًا عن المعالجات الأخرى، لذا يمكن إضافة تفاعلات جديدة دون تعديل الناشر.

public class UpdateInventoryHandler
    : INotificationHandler<OrderPlacedNotification>
{
    public Task Handle(OrderPlacedNotification n, CancellationToken ct)
    {
        // decrement stock...
        return Task.CompletedTask;
    }
}

النشر

لرفع إشعار، احقن IPublisher (أو IMediator) واستدعِ Publish. يُستدعى كل معالج مسجّل.

public class CreateOrderHandler(AppDbContext db, IPublisher publisher)
    : IRequestHandler<CreateOrderCommand, int>
{
    public async Task<int> Handle(CreateOrderCommand c, CancellationToken ct)
    {
        var order = new Order { CustomerId = c.CustomerId };
        db.Orders.Add(order);
        await db.SaveChangesAsync(ct);
        await publisher.Publish(
            new OrderPlacedNotification(order.Id, c.CustomerId), ct);
        return order.Id;
    }
}

فك اقتران الآثار الجانبية

تحافظ الإشعارات على تركيز حالة الاستخدام الأساسية. فوضع طلب يسجّل الطلب وينشر حدثًا فقط، بينما تعيش عمليات إرسال البريد الإلكتروني وإدارة المخزون في معالجاتها الخاصة. هذا تطبيق عملي لمبدأ الانفتاح والإغلاق.

// CreateOrderHandler does NOT know about email or inventory

استراتيجية النشر

بشكل افتراضي، ينتظر MediatR كل معالج إشعار بالتسلسل. وإذا طرح أحدها استثناءً، فلن تعمل المعالجات اللاحقة. ويمكنك توفير ناشر مخصص لتشغيلها بالتوازي.

builder.Services.AddMediatR(cfg =>
{
    cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
    cfg.NotificationPublisher = new TaskWhenAllPublisher();
});

معالجة حالات الفشل

نظرًا إلى استقلالية المعالجات، حدّد معنى الفشل. بالنسبة إلى الآثار الجانبية غير الحرجة، التقط الاستثناء وسجّل الخطأ داخل المعالج حتى لا يؤدي فشل واحد إلى تعطيل المعالجات الأخرى.

public async Task Handle(OrderPlacedNotification n, CancellationToken ct)
{
    try { await _email.SendAsync(n.CustomerId, ct); }
    catch (Exception ex) { _logger.LogError(ex, "email failed"); }
}

نمط أحداث المجال

من الأنماط الشائعة أن تجمع الكيانات أحداث المجال، ثم تنشرها كلها بعد حفظ المعاملة. ويضمن ذلك إطلاق الأحداث فقط بعد تثبيت التغيير.

await db.SaveChangesAsync(ct);
foreach (var domainEvent in order.Events)
    await publisher.Publish(domainEvent, ct);
order.Events.Clear();

الإشعارات في مقابل قوائم انتظار الرسائل

إشعارات MediatR تعمل داخل العملية وبشكل متزامن ضمن الطلب. أما التسليم بين الخدمات أو التسليم الموثوق والدائم، فانشر الرسالة إلى وسيط رسائل فعلي مثل RabbitMQ أو Azure Service Bus بدلًا من ذلك.

// In-process reactions  -> MediatR notifications
// Cross-service / durable -> message broker

اختبار الإشعارات

يمكنك التحقق من أن المعالج ينشر الحدث الصحيح بتمرير كائن محاكاة من IPublisher والتأكد من استدعائه.

var publisher = new Mock<IPublisher>();
var handler = new CreateOrderHandler(db, publisher.Object);
await handler.Handle(new CreateOrderCommand(1, []), default);
publisher.Verify(p => p.Publish(
    It.IsAny<OrderPlacedNotification>(), default), Times.Once);

تحقق سريع

تحقّق من فهمك لنموذج الإشعارات.

مراجعة

لقد تعلّمت الإشعارات والأحداث:

  • يمثّل INotification بثًا يضم صفرًا أو أكثر من INotificationHandler.
  • انشر باستخدام IPublisher.Publish لاستدعاء جميع المشتركين.
  • تفصل الإشعارات الآثار الجانبية عن بعضها وتتبع مبدأ الانفتاح والإغلاق.
  • تعمل الإشعارات داخل العملية؛ استخدم وسيط رسائل للأحداث العابرة للخدمات أو الدائمة.

وبذلك تكتمل دورة CQRS وMediatR.

الأسئلة الشائعة

هل درس «الإشعارات والأحداث» مجاني؟

نعم — نص درس «الإشعارات والأحداث» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «الإشعارات والأحداث»؟

انشروا أحداث المجال باستخدام MediatR تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «الإشعارات والأحداث»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مفاهيم CQRS
  2. الأوامر والمعالجات باستخدام MediatR
  3. سلوكيات مسار المعالجة
  4. الإشعارات والأحداث
← العودة إلى C# Academy