TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 549 subscribers
Post #197 113
ساخت یک توزیع‌کننده (Dispatcher) سفارشی Domain Events در NET. 🧱


Domain events
یک راه قدرتمند برای جداسازی (decouple) بخش‌های مختلف سیستم شما هستند. به جای اتصال سفت و سخت منطق خود، می‌توانید رویدادها را منتشر کرده و بخش‌های دیگر کدتان را به آن رویدادها مشترک (subscribe) کنید. این الگو به ویژه در طراحی دامنه محور (Domain-Driven Design - DDD) ارزشمند است، جایی که منطق بیزینس باید متمرکز و منسجم باقی بماند.

در این مقاله، ما نحوه پیاده‌سازی یک توزیع‌کننده رویداد دامنه سبک و سفارشی را در NET. بررسی خواهیم کرد. منطق اصلی توزیع نباید به کتابخانه‌های شخص ثالث وابسته باشد.

📌ما پوشش خواهیم داد:


🔹 چرا ممکن است بخواهید از publish-subscribe در اپلیکیشن خود استفاده کنید.

🔹 نحوه تعریف انتزاع‌های پایه رویداد دامنه.

🔹 نحوه پیاده‌سازی و ثبت handlerها.

🔹 نحوه ساخت یک توزیع‌کننده رویدادهای دامنه.

🔹 مزایا و معایب و زمان در نظر گرفتن گزینه‌های دیگر.

چرا Domain Events اهمیت دارند؟ 🤔

قبل از شیرجه زدن در پیاده‌سازی، بیایید مشکلی را که رویدادهای دامنه حل می‌کنند، درک کنیم. این کد با اتصال سفت و سخت را در نظر بگیرید:
public class UserService
{
public async Task RegisterUser(string email, string password)
{
var user = new User(email, password);
await _userRepository.SaveAsync(user);

// 🔗 مستقیماً به سرویس ایمیل متصل است
await _emailService.SendWelcomeEmail(user.Email);

// 🔗 مستقیماً به سرویس آنالیتیکس متصل است
await _analyticsService.TrackUserRegistration(user.Id);

// اگر بخواهیم ویژگی‌های بیشتری اضافه کنیم چه؟
// این متد به رشد خود ادامه خواهد داد...
}
}


با رویدادهای دامنه، می‌توانیم این را جدا کنیم: ✨
public class UserService
{
public async Task RegisterUser(string email, string password)
{
var user = new User(email, password);
await _userRepository.SaveAsync(user);

// رویداد را منتشر کن - بگذار بخش‌های دیگر سیستم واکنش نشان دهند
await _domainEventsDispatcher.DispatchAsync(
[new UserRegisteredDomainEvent(user.Id, user.Email)]);
}
}


اکنون UserService فقط بر روی ثبت نام کاربر تمرکز دارد، در حالی که دغدغه‌های دیگر از طریق event handlerها مدیریت می‌شوند.

انتزاع‌های پایه 🧬

بیایید با تعریف دو اینترفیس ساده که پایه و اساس سیستم رویداد ما را تشکیل می‌دهند، شروع کنیم:
// اینترفیس نشانگر برای تمام رویدادهای دامنه.
public interface IDomainEvent { }

// اینترفیس جنریک برای مدیریت رویدادهای دامنه.
public interface IDomainEventHandler<in T> where T : IDomainEvent
{
Task Handle(T domainEvent, CancellationToken cancellationToken = default);
}


پیاده‌سازی Handlerهای نمونه 📧📊

بیایید چند handler نمونه اضافه کنیم که نشان می‌دهند چگونه بخش‌های مختلف سیستم شما می‌توانند به یک رویداد یکسان واکنش نشان دهند:
// ارسال ایمیل خوش‌آمدگویی هنگام ثبت نام کاربر
internal sealed class SendWelcomeEmailHandler(...)
: IDomainEventHandler<UserRegisteredDomainEvent>
{
// ...
}

// ردیابی ثبت نام کاربر جدید در آنالیتیکس
internal sealed class TrackUserRegistrationHandler(...)
: IDomainEventHandler<UserRegisteredDomainEvent>
{
// ...
}


برای اینکه این کار کند، باید handlerهای خود را در کانتینر DI ثبت کنیم. می‌توانید این ثبت را با اسکن اسمبلی با Scrutor خودکار کنید. نکته مهم این است که چندین handler می‌توانند به یک رویداد یکسان واکنش نشان دهند.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →