我花了一些时间学习"事件采购"工作以及如何在C#中实现它,我在某些时候陷入困境。 由于在没有代码的情况下很难描述我的问题,我首先会给你一个简化版本的代码。我删除了所有不需要的代码并留下了相关部分。
public interface IEvent { }
public class UserCreated : IEvent { }
public class UserDeleted : IEvent { }
public interface IEventSourcable
{
ICollection<IEvent> History { get; }
void ApplyEvent(IEvent e);
}
public abstract class EntityBase : IEventSourcable
{
public ICollection<IEvent> History { get; }
public void ApplyEvent(IEvent e)
{
History.Add(e);
}
}
public class User : EntityBase
{
public void ApplyEvent(UserCreated e)
{
base.ApplyEvent(e)
}
}
我想做的是如果没有实现匹配方法,则阻止使用基本方法i。即
User u = new User();
u.ApplyEvent(new UserCreated());
应该工作并调用User中的方法(它确实如此)但是
u.ApplyEvent(new UserDeleted());
不应该调用基本方法,但在编译时会出错。
我已经看到了不同的方法会产生运行时错误,或者如果没有像
那样实现匹配方法,则会忽略问题只需覆盖方法并检查类型
public class User : EntityBase
{
public override void ApplyEvent(IEvent e)
{
if (e is UserCreated)
ApplyEvent((UserCreated)e);
else if (e is UserDeleted)
ApplyEvent((UserDeleted)e);
else
throw new UnknownEventException(); // Or handle it however
}
}
使用动态运算符
public abstract class EntityBase : IEventSourcable
{
public ICollection<IEvent> History { get; }
public void ApplyEvent(IEvent e)
{
History.Add(e);
((dynamic)this).Apply((dynamic)e);
}
}
public class User : EntityBase
{
public override void Apply(UserCreated e)
{
// do something
}
}
我知道我可以用上述任何一种方式来做,但我更感兴趣的是我能想到的是否可能。
答案 0 :(得分:0)
您可以显式实现接口,这可以防止在具体实例上出现不需要的事件类型:
public abstract class EntityBase : IEventSourcable
{
ICollection<IEvent> IEventSourcable.History { get; }
void IEventSourcable.ApplyEvent(IEvent e)
{
// Do the magic
}
protected void ApplyEvent(IEvent e)
{
(this as IEventSourcable).ApplyEvent(e);
}
}
public class User : EntityBase
{
public void ApplyEvent(UserCreated e)
{
base.ApplyEvent(e);
}
}
然而,这不会阻止消费者转向IEventSourcable
并添加任意事件:
IEventSourcable u = new User();
u.ApplyEvent(new UserCreated());
u.ApplyEvent(new UserDeleted());