/// <summary> /// Creates or updates the snapshot for the given aggregate root. /// </summary> /// <param name="aggregateRoot">The aggregate root on which the snapshot is created or updated.</param> public override void CreateOrUpdateSnapshot(ISourcedAggregateRoot aggregateRoot) { ISnapshot snapshot = aggregateRoot.CreateSnapshot(); SnapshotDataObject dataObj = SnapshotDataObject.CreateFromAggregateRoot(aggregateRoot); PropertyBag insertOrUpdateData = new PropertyBag(dataObj); var key = new EventNumberSnapshotMappingKey(aggregateRoot.GetType().AssemblyQualifiedName, aggregateRoot.ID); if (this.HasSnapshot(aggregateRoot.GetType(), aggregateRoot.ID)) { string aggregateRootTypeName = aggregateRoot.GetType().AssemblyQualifiedName; Guid aggregateRootId = aggregateRoot.ID; ISpecification <SnapshotDataObject> spec = Specification <SnapshotDataObject> .Eval( p => p.AggregateRootType == aggregateRootTypeName && p.AggregateRootID == aggregateRootId); this.SnapshotStorage.Update <SnapshotDataObject>(insertOrUpdateData, spec); this.Committed = false; if (snapshotMapping.ContainsKey(key)) { snapshotMapping[key] = snapshot; } else { snapshotMapping.Add(key, snapshot); } } else { this.SnapshotStorage.Insert <SnapshotDataObject>(insertOrUpdateData); this.Committed = true; snapshotMapping.Add(key, snapshot); } }
/// <summary> /// Gets the instance of the aggregate root with the specified identifier. /// </summary> /// <param name="id">The identifier of the aggregate root.</param> /// <returns>The instance of the aggregate root with the specified identifier.</returns> public override TAggregateRoot Get <TAggregateRoot>(Guid id) { string aggregateRootType = typeof(TAggregateRoot).AssemblyQualifiedName; ISpecification <SnapshotDataObject> spec = Specification <SnapshotDataObject> .Eval(p => p.AggregateRootID == id && p.AggregateRootType == aggregateRootType); SnapshotDataObject snapshotDataObject = this.storage.SelectFirstOnly <SnapshotDataObject>(spec); if (snapshotDataObject == null) { throw new RepositoryException("The aggregate (id={0}) cannot be found in the domain repository.", id); } ISnapshot snapshot = snapshotDataObject.ExtractSnapshot(); TAggregateRoot aggregateRoot = this.CreateAggregateRootInstance <TAggregateRoot>(); aggregateRoot.BuildFromSnapshot(snapshot); return(aggregateRoot); }
/// <summary> /// Commits the changes registered in the domain repository. /// </summary> //protected override void DoCommit() //{ // foreach (ISourcedAggregateRoot aggregateRoot in this.SaveHash) // { // SnapshotDataObject snapshotDataObject = SnapshotDataObject.CreateFromAggregateRoot(aggregateRoot); // var aggregateRootId = aggregateRoot.ID; // var aggregateRootType = aggregateRoot.GetType().AssemblyQualifiedName; // ISpecification<SnapshotDataObject> spec = Specification<SnapshotDataObject>.Eval(p => p.AggregateRootID == aggregateRootId && p.AggregateRootType == aggregateRootType); // var firstMatch = this.storage.SelectFirstOnly<SnapshotDataObject>(spec); // if (firstMatch != null) // this.storage.Update<SnapshotDataObject>(new PropertyBag(snapshotDataObject), spec); // else // this.storage.Insert<SnapshotDataObject>(new PropertyBag(snapshotDataObject)); // foreach (var evnt in aggregateRoot.UncommittedEvents) // { // this.EventBus.Publish(evnt); // } // } // if (this.DistributedTransactionSupported) // { // using (TransactionScope ts = new TransactionScope()) // { // this.storage.Commit(); // this.EventBus.Commit(); // ts.Complete(); // } // } // else // { // this.storage.Commit(); // this.EventBus.Commit(); // } //} protected override async Task DoCommitAsync(CancellationToken cancellationToken) { foreach (ISourcedAggregateRoot aggregateRoot in this.SaveHash) { SnapshotDataObject snapshotDataObject = SnapshotDataObject.CreateFromAggregateRoot(aggregateRoot); var aggregateRootId = aggregateRoot.ID; var aggregateRootType = aggregateRoot.GetType().AssemblyQualifiedName; ISpecification <SnapshotDataObject> spec = Specification <SnapshotDataObject> .Eval(p => p.AggregateRootID == aggregateRootId && p.AggregateRootType == aggregateRootType); var firstMatch = this.storage.SelectFirstOnly <SnapshotDataObject>(spec); if (firstMatch != null) { this.storage.Update <SnapshotDataObject>(new PropertyBag(snapshotDataObject), spec); } else { this.storage.Insert <SnapshotDataObject>(new PropertyBag(snapshotDataObject)); } foreach (var evnt in aggregateRoot.UncommittedEvents) { this.EventBus.Publish(evnt); } } if (this.DistributedTransactionSupported) { using (TransactionScope ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await this.storage.CommitAsync(cancellationToken); await this.EventBus.CommitAsync(cancellationToken); ts.Complete(); } } else { await this.storage.CommitAsync(cancellationToken); await this.EventBus.CommitAsync(cancellationToken); } }
/// <summary> /// Gets the snapshot for the aggregate root with the given type and identifier. /// </summary> /// <param name="aggregateRootType">The type of the aggregate root.</param> /// <param name="id">The identifier of the aggregate root.</param> /// <returns>The snapshot instance.</returns> public override ISnapshot GetSnapshot(Type aggregateRootType, Guid id) { var key = new EventNumberSnapshotMappingKey(aggregateRootType.AssemblyQualifiedName, id); if (snapshotMapping.ContainsKey(key)) { return(snapshotMapping[key]); } string aggregateRootTypeName = aggregateRootType.AssemblyQualifiedName; ISpecification <SnapshotDataObject> spec = Specification <SnapshotDataObject> .Eval( p => p.AggregateRootType == aggregateRootTypeName && p.AggregateRootID == id); SnapshotDataObject dataObj = this.SnapshotStorage.SelectFirstOnly <SnapshotDataObject>(spec); if (dataObj == null) { return(null); } ISnapshot snapshot = dataObj.ExtractSnapshot(); this.snapshotMapping.Add(key, snapshot); return(snapshot); }