【问题标题】:JOliver EventStore SnapshottingJOliver EventStore 快照
【发布时间】:2020-10-27 17:13:10
【问题描述】:

假设我有这个代码:

private void CreateSnapshots(IEnumerable<StreamHead> streams)
{
    foreach (StreamHead head in streams)
    {
        IAggregate aggregate = ???;
        IMemento memento = aggregate.GetSnapshot();

        var snapshot = new Snapshot(head.StreamId, head.SnapshotRevision + 1, memento);

        eventStore.AddSnapshot(snapshot);

        observer.Notify(new SnapshotTaken(head.StreamId, head.HeadRevision));
    }
}

我如何知道要为当前流加载什么聚合?我也在使用 CommonDomain。里面有东西吗?

谢谢

【问题讨论】:

  • 刚刚注意到 OptimisticEventStore.OpenStream(Guid streamId, int minRevision, int maxRevision) 对提交标头没有任何作用。这就是问题所在吗?
  • -> PopulateStream(int minRevision, int maxRevision, IEnumerable commits)

标签: cqrs neventstore


【解决方案1】:

EventStore 的快照方面需要一点爱。我试图使 IStoreEvents 接口适合使用单个聚合。我还尝试确保快照不会干扰或妨碍正常使用。

自 v2.0 发布以来,我现在将注意力转向 v2.1,我将能够进行一些与此相关的小 API 更改。同时,您最好的选择可能是在进行快照时完全绕过 IStoreEvents。

另一种选择是让快照代码与常规代码一起在进程内运行。加载聚合需要快照时,您可以轻松地将对该聚合的引用异步推送到快照代码。通过这种方式,您实际上不必执行加载,因为您已经拥有聚合。

【讨论】:

    【解决方案2】:

    我找到了适合我的解决方案(这绝对是一个 hack)。它仍然是带外快照。这是它的sample 的实际应用。

    private void CreateSnapshots(IEnumerable<StreamHead> streams)
    {
        foreach (StreamHead head in streams)
        {
            //NOTE: This uses a patched version of EventStore that loads commit headers in OptimisticEventStream.PopulateStream()
            // <code>
            // this.identifiers.Add(commit.CommitId);
            // this.headers = this.headers.Union(commit.Headers).ToDictionary(k => k.Key, k => k.Value);
            // </code>
            var stream = eventStore.OpenStream(head.StreamId, int.MinValue, int.MaxValue);
    
            //NOTE: Nasty hack but it works.
            var aggregateType = stream.UncommittedHeaders.Where(p=>p.Key=="AggregateType").First();
            var type = aggregateTypeResolver(aggregateType.Value.ToString());
    
            MethodInfo methodInfo = typeof(IRepository).GetMethod("GetById");
            MethodInfo method = methodInfo.MakeGenericMethod(type);
    
            object o = method.Invoke(repository, new object[]{head.StreamId, head.HeadRevision});
            var aggregate = (IAggregate) o;
    
            IMemento memento = aggregate.GetSnapshot();
    
            var snapshot = new Snapshot(head.StreamId, head.HeadRevision, memento);
    
            eventStore.AddSnapshot(snapshot);
    
            observer.Notify(new SnapshotTaken(head.StreamId, head.HeadRevision));
        }
    }
    

    【讨论】:

    • 这个最近的提交 (github.com/joliver/EventStore/commit/…) 直接暴露了底层的持久性。这允许更好地访问实际提交本身。此外,您可能希望将聚合的构造委托给某种工厂类,而不是进行所有这些疯狂的反射。
    • 我会试一试,但乍一看,我仍然没有找到一种方法来找到要从流中加载的聚合的类型。跨度>
    • 如果您使用的是 CommonDomain 项目,则类型将存储在每次提交的标头中。因为您可以访问原始提交,所以您可以访问标头并获取类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    相关资源
    最近更新 更多