मैं jbogard द्वारा निम्नलिखित पैटर्न अपनाया है:ईवेंट हैंडलर द्वारा उठाए गए डोमेन ईवेंट को कैसे प्रबंधित करें?
http://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/
कल्पना कीजिए इकाई Coupon
और घटना CouponActivatedEvent
निम्नलिखित:
public class Coupon : DomainEntity
{
public virtual User User { get; private set; }
// ...omitted...
public void Activate(User user)
{
if (User != null)
throw new InvalidOperationException("Coupon already activated");
User = user;
Events.Add(new CouponActivatedEvent(this));
}
}
निम्नलिखित ईवेंट हैंडलर CouponActivatedHandler
:
public class CouponActivatedHandler : IDomainEventHandler<CouponActivatedEvent>
{
public void Handle(CouponActivatedEvent e)
{
// user gets 5 credits because coupon was activated
for (int i = 0; i < 5; i++)
{
e.Coupon.User.AddCredit(); // raises UserReceivedCreditEvent and CreditCreatedEvent
}
}
}
निम्नलिखितपर DbContext
(इकाई की रूपरेखा 6), jbogard के ब्लॉग पोस्ट से लियाओवरराइड:
public override int SaveChanges()
{
var domainEventEntities = ChangeTracker.Entries<IDomainEntity>()
.Select(po => po.Entity)
.Where(po => po.Events.Any())
.ToArray();
foreach (var entity in domainEventEntities)
{
var events = entity.Events.ToArray();
entity.Events.Clear();
foreach (var domainEvent in events)
{
_dispatcher.Dispatch(domainEvent);
}
}
return base.SaveChanges();
}
अब हम एक कूपन सक्रिय करते हैं, इस CouponActivatedEvent
बढ़ा देंगे। SaveChanges
पर कॉल करते समय, हैंडलर निष्पादित किया जाएगा, और UserReceivedCreditEvent
और CreditCreatedEvent
उठाया जाएगा। हालांकि उन्हें संभाला नहीं जाएगा। क्या मैं पैटर्न को गलत समझ रहा हूं? या SaveChanges
ओवरराइड उचित नहीं है?
मैं एक पाश है कि जब तक कोई नया घटनाओं base.SaveChanges();
पर जाने से पहले उठाए गए हैं दोहराया जाएगा बनाने पर विचार किया है ... लेकिन मुझे चिंता है कि अनंत छोरों गलती से पैदा करेगा हूँ। इस तरह:
public override int SaveChanges()
{
do
{
var domainEventEntities = ChangeTracker.Entries<IDomainEntity>()
.Select(po => po.Entity)
.Where(po => po.Events.Any())
.ToArray();
foreach (var entity in domainEventEntities)
{
var events = entity.Events.ToArray();
entity.Events.Clear();
foreach (var domainEvent in events)
{
_dispatcher.Dispatch(domainEvent);
}
}
}
while (ChangeTracker.Entries<IDomainEntity>().Any(po => po.Entity.Events.Any()));
return base.SaveChanges();
}
धन्यवाद, आपने मेरे लिए कई चीजों को स्पष्ट किया है। क्या आप एक उदाहरण परियोजना के बारे में जानते हैं जिस तरह से आप वर्णन करते हैं? मुझे लगता है कि मुझे यह विचार मिलता है, मैं बस इसे ठीक से कार्यान्वित करने के बारे में अनिश्चित हूं। – Korijn
उदाहरण, वास्तव में नहीं। लेकिन इसे शुरू करना, अभ्यास सही बनाता है। क्या, ध्यान दें कि बोझिल क्या लगता है, रिफैक्टर आदि का प्रयास करें। डीडीडी इसे करके सीखा है। – MikeSW
मुझे अब यह मिल गया है, विशेष रूप से * ईवेंट हैंडलर अतीत में हुई चीजों पर प्रतिक्रिया करते हैं * बहुत समझाया। – Korijn