机械式的答案……您可以在其中构思出许多变化。基本上,您必须决定谁将收集所有这些事件:根(此处显示)或每个实体(此处未显示的方法)分别收集。从技术上讲,您有很多选项可以实现如下所示的观察行为(想想 Rx、手动编码的调解器等)。我将大部分基础设施代码浮现在实体中(此处缺少抽象)。
public class DeliveryRun {
Dictionary<Type, Action<object>> _handlers = new Dictionary<Type, Action<object>>();
List<object> _events = new List<object>();
DeliveryManifest _manifest;
public DeliverRun() {
Register<DeliveryManifestAssigned>(When);
Register<DeliveryManifestChanged>(When);
}
public void AssignManifest(...) {
Apply(new DeliveryManifestAssigned(...));
}
public void ChangeManifest(...) {
_manifest.Change(...);
}
public void Initialize(IEnumerable<object> events) {
foreach(var @event in events) Play(@event);
}
internal void NotifyOf(object @event) {
Apply(@event);
}
void Register<T>(Action<T> handler) {
_handlers.Add(typeof(T), @event => handler((T)@event));
}
void Apply(object @event) {
Play(@event);
Record(@event);
}
void Play(object @event) {
Action<object> handler;
if(_handlers.TryGet(@event.GetType(), out handler)) {
handler(@event); //dispatches to those When methods
}
}
void Record(object @event) {
_events.Add(@event);
}
void When(DeliveryManifestAssigned @event) {
_manifest = new DeliveryManifest(this);
_manifest.Initialize(@event);
}
void When(DeliverManifestChanged @event) {
_manifest.Initialize(@event);
}
}
public class DeliveryManifest {
Dictionary<Type, Action<object>> _handlers = new Dictionary<Type, Action<object>>();
DeliveryRun _run;
public DeliveryManifest(DeliveryRun run) {
_run = run;
Register<DeliveryManifestAssigned>(When);
Register<DeliveryManifestChanged>(When);
}
public void Initialize(object @event) {
Play(@event);
}
public void Change(...) {
Apply(new DeliveryManifestChanged(...));
}
void Register<T>(Action<T> handler) {
_handlers.Add(typeof(T), @event => handler((T)@event));
}
void Play(object @event) {
Action<object> handler;
if(_handlers.TryGet(@event.GetType(), out handler)) {
handler(@event); //dispatches to those When methods
}
}
void Apply(object @event) {
_run.NotifyOf(@event);
}
void When(DeliveryManifestAssigned @event) {
//...
}
void When(DeliveryManifestChanged @event) {
//...
}
}
PS我把这个“乱七八糟”编码了,请原谅我的编译错误。