【发布时间】:2014-10-31 15:04:06
【问题描述】:
我已经通过 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
}
}
}
以下 SaveChanges 覆盖 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();
}
【问题讨论】:
标签: c# entity-framework domain-driven-design