public static Snapshot ToSnapshot(this IAggregateRoot aggregate) { var data = JsonConvert.SerializeObject(aggregate, SerializerSettings); var metadata = JsonConvert.SerializeObject(aggregate.GetType().AssemblyQualifiedName, SerializerSettings); return(new Snapshot(Guid.NewGuid(), aggregate.Id, aggregate.GetType().Name, aggregate.Version, data, metadata, DateTime.Now)); }
private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = _aggregateSnapshotter.RestoreFromSnapshot(aggregateRootType, aggregateRootId); if (aggregateRoot == null) { return(false); } if (aggregateRoot.GetType() != aggregateRootType || aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("AggregateRoot recovery from snapshot is invalid as the aggregateRootType or aggregateRootId is not matched. Snapshot: [aggregateRootType:{0},aggregateRootId:{1}], expected: [aggregateRootType:{2},aggregateRootId:{3}]", aggregateRoot.GetType(), aggregateRoot.UniqueId, aggregateRootType, aggregateRootId)); } var aggregateRootTypeName = _typeNameProvider.GetTypeName(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeName, aggregateRoot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return(true); }
public async Task <int> Save(IAggregateRoot aggregateRoot) { var dt = new DataTable(); dt.Columns.Add("Data", typeof(string)); foreach (var e in aggregateRoot.GetEvents()) { dt.Rows.Add(e.Serialize()); } using (var connection = new SqlConnection(_connectionString)) { var argumentObject = new { AggregateID = aggregateRoot.Id, Name = StreamName(aggregateRoot.GetType(), aggregateRoot.Id), Type = aggregateRoot.GetType().AssemblyQualifiedName, aggregateRoot.Version, Batch = dt.AsTableValuedParameter("EventValueType") }; return(await connection.ExecuteAsync("Event_Ins", argumentObject, commandType : CommandType.StoredProcedure)); } }
private IAggregateSnapshot BuildSnapshotFromAggregate(IAggregateRoot aggregate) { var aggregateTypeName = aggregate.GetType().Name.Substring(aggregate.GetType().Name.LastIndexOf(".") + 1); var snapshotTypeName = $"ProgramaPontos.Domain.Snapshots.{aggregateTypeName}Snapshot, ProgramaPontos.Domain"; var snapshotType = Type.GetType(snapshotTypeName); return((IAggregateSnapshot)Activator.CreateInstance(snapshotType, aggregate)); }
public Aggregate(string identifier, Version expectedVersion, IAggregateRoot root) { this.Identifier = identifier ?? throw new ArgumentNullException(nameof(identifier)); this.ExpectedVersion = expectedVersion; this.Root = root ?? throw new ArgumentNullException(nameof(root)); this.RootType = root.GetType().Name; }
/// <summary> /// Registers the specified aggregate. /// </summary> /// <param name="aggregate">The aggregate.</param> /// <exception cref="System.ArgumentNullException">Aggregate null exception.</exception> public virtual void Register(IAggregateRoot aggregate) { if (aggregate == null) { throw new ArgumentNullException("aggregate"); } _registered = aggregate; // Get instance methods named Apply with one parameter returning void var applyMethods = aggregate.GetType() .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(m => m.Name == "Apply" && m.GetParameters().Length == 1 && m.ReturnType == typeof(void)) .Select( m => new { Method = m, MessageType = m.GetParameters().Single().ParameterType }); foreach (var apply in applyMethods) { var applyMethod = apply.Method; _handlers.Add(apply.MessageType, m => applyMethod.Invoke(aggregate, new[] { m })); } }
private static void UpdateStream(IAggregateRoot stream, Guid commandId) { var notCommited = stream.NotCommitedChanges().ToList(); if (!notCommited.Any()) { return; } var versionCnt = stream.Metadata.Version; foreach (var bEvent in notCommited) { var aggregateType = stream.GetType().FullName; var new_version = ++versionCnt; bEvent.EventId = $"{stream.Metadata.AggregateId}_{new_version}"; bEvent.Metadata = new SourcedEventMetadata { Version = new_version, CommandId = commandId, AggregateId = stream.Metadata.AggregateId, AggregateType = aggregateType, Date = DateTime.UtcNow }; } }
/// <summary> /// Saves the specified aggregate. /// </summary> /// <param name="aggregate">The aggregate.</param> /// <param name="uncommitedEvents">The uncommited events.</param> /// <param name="commitId">The commit id.</param> /// <param name="updateHeaders">The update headers.</param> /// <exception cref="ProCenter.Infrastructure.EventStore.ConflictingCommandException"></exception> /// <exception cref="ProCenter.Infrastructure.EventStore.PersistenceException"></exception> public virtual void Save(IAggregateRoot aggregate, IEnumerable <IDomainEvent> uncommitedEvents, Guid commitId, Action <IDictionary <string, object> > updateHeaders) { var headers = PrepareHeaders(aggregate, updateHeaders); var eventStore = _eventStoreFactory.Build(aggregate.GetType()); while (true) { var stream = PrepareStream(eventStore, aggregate, headers, uncommitedEvents); var commitEventCount = stream.CommittedEvents.Count; try { stream.CommitChanges(commitId); return; } catch (DuplicateCommitException) { stream.ClearChanges(); return; } catch (ConcurrencyException e) { if (this.ThrowOnConflict(stream, commitEventCount)) { throw new ConflictingCommandException(e.Message, e); } stream.ClearChanges(); } catch (StorageException e) { throw new PersistenceException(e.Message, e); } } }
public void Save(IAggregateRoot aggregateRoot) { var set = _cache.GetOrAdd(aggregateRoot.GetType(), () => new HashSet <IAggregateRoot>()); if (!set.Add(aggregateRoot)) { return; } var eventPublisher = aggregateRoot as IEventPublisher; if (eventPublisher == null) { return; } var events = eventPublisher.GetEvents(); if (events.IsEmpty()) { return; } _eventBus.Publish(events); }
private async Task<List<IEventMessageDraft>> CreateEventMessagesAsync(IAggregateRoot aggregate, IReadOnlyCollection<DomainAggregateEvent> events) { var messages = new List<IEventMessageDraft>(); Guid? aggregateClassId = entityTypeManager.TryGetClassInfoByClrType(aggregate.GetType())?.Id; foreach (DomainAggregateEvent ev in events) { IEventMessageDraft message = await eventMessageFactory.CreateMessageAsync(ev); if (aggregateClassId != null) { message.SetMetadata(BasicEventMetadataNames.AggregateClassId, aggregateClassId.Value.ToString()); } if (aggregate is ITenantOwned tenantOwned) { message.SetMetadata(BasicEventMetadataNames.AggregateTenantId, tenantOwned.TenantId?.ToString()); } if (message.Metadata.GetEventId() == null) { message.SetMetadata(BasicEventMetadataNames.EventId, Guid.NewGuid().ToString()); } messages.Add(message); } return messages; }
private MethodInfo FindApply(object eventMessage) { return((from methodInfo in _aggregateRoot.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) from parameterInfo in methodInfo.GetParameters() where parameterInfo.ParameterType == eventMessage.GetType() && methodInfo.Name.Contains("Handle") select methodInfo).Single()); }
public bool Exists(IAggregateRoot aggregate) { if (aggregate == null) { return(false); } return(_memoryCache.TryGetValue(CacheKey(aggregate.GetType(), aggregate.Id), out object value)); }
public IAggregateRoot Set(IAggregateRoot aggregate) { if (aggregate == null) { return(null); } return(this.Set(aggregate.GetType(), aggregate.Id, aggregate)); }
public async Task AppendUncommittedEventsToNewStream([Frozen] IEventStoreConnection connection, IAggregateRoot <TestAggregate> aggregateRoot, EventStoreRepository sut) { await sut.SaveAsync(aggregateRoot); await connection.Received(1).AppendToStreamAsync($"{aggregateRoot.GetType().Name}-{aggregateRoot.Id}", aggregateRoot.OriginalVersion, aggregateRoot.GetUncommittedEvents()); }
Task IUnitOfWorkRepository.PersistUpdateOfAsync(IAggregateRoot entity, IDbConnection dbConnection, IDbTransaction dbTransaction) { if (entity is TEntity == false) { throw new System.Exception($"Expecting {typeof(TEntity).Name} but {entity.GetType().Name}"); } return(PersistUpdateOfAsync((TEntity)entity, dbConnection, dbTransaction)); }
public Task Save(IAggregateRoot aggregateRoot) { var events = aggregateRoot .GetEvents() .Select(ToEventData); return(eventStoreConnection.AppendToStreamAsync(StreamName(aggregateRoot.GetType(), aggregateRoot.Id), aggregateRoot.Version, events)); }
public void Add(IAggregateRoot aggregateRoot) { Assertions.NotNull(aggregateRoot, "aggregateRoot"); var key = string.Concat(aggregateRoot.GetType().FullName, "@", aggregateRoot.Id); _trackingAggregateRoots.TryAdd(key, aggregateRoot); }
public void Add(IAggregateRoot aggregate) { if (aggregate == null || !aggregate.GetType().Equals(typeof(TAggregateRoot))) { throw new Exception($"类型不是{typeof(TAggregateRoot).Name}"); } this.Add((TAggregateRoot)aggregate); }
public SnapshotConfig GetConfiguration(IAggregateRoot aggregate) { if (entitySnapshotsConfigs.TryGetValue(aggregate.GetType(), out var config)) { return(config); } return(defaultSnapshotConfig); }
internal static AggregateSnapshot MakeSnapshot(this IAggregateRoot aggregate) { return(new AggregateSnapshot { AggregateId = aggregate.Id, AggregateType = aggregate.GetType(), Version = aggregate.Version, State = aggregate.State, }); }
private DomainEventStreamMessage CreateMessage(IAggregateRoot aggregateRoot) { return new DomainEventStreamMessage( ObjectId.GenerateNewStringId(), aggregateRoot.UniqueId, aggregateRoot.Version + 1, aggregateRoot.GetType().FullName, aggregateRoot.GetChanges(), new Dictionary<string, string>()); }
public void Delete(IAggregateRoot aggregateRoot) { HashSet <IAggregateRoot> set; if (!_cache.TryGetValue(aggregateRoot.GetType(), out set)) { return; } set.RemoveWhere(p => p.Id.GetHashCode() == aggregateRoot.Id.GetHashCode()); }
public async Task TakeAndSaveAsync(IAggregateRoot aggregate) { var snapshot = aggregate.ToSnapshot(); string insertScript = EventRepositoryScriptsAsStrings.InsertSnapshot(); await _databaseProvider.ExecuteAsync(insertScript, snapshot); Log.Information($"Snapshot for aggregate {aggregate.GetType().Name} has been created from version {aggregate.Version}"); }
private DomainEventStreamMessage CreateMessage(IAggregateRoot aggregateRoot) { return(new DomainEventStreamMessage( ObjectId.GenerateNewStringId(), aggregateRoot.UniqueId, aggregateRoot.Version + 1, aggregateRoot.GetType().FullName, aggregateRoot.GetChanges(), new Dictionary <string, string>())); }
public void Handle(IAggregateRoot root, IDomainEvent ev) { MethodInvoker invoker; if (!_handlers.TryGetValue(ev.GetType(), out invoker)) { throw new InvalidOperationException(string.Format("Apply method for event [{0}] wasn't resolved in [{1}]", ev.GetType().Name, root.GetType().Name)); } invoker.Invoke(root, new object[] {ev}); }
private DomainEventStream BuildDomainEventStream(IAggregateRoot aggregateRoot, IEnumerable <IDomainEvent> changedEvents, ProcessingCommand processingCommand) { return(new DomainEventStream( processingCommand.Message.Id, aggregateRoot.UniqueId, _aggregateRootTypeProvider.GetTypeCode(aggregateRoot.GetType()), aggregateRoot.Version + 1, DateTime.Now, changedEvents, processingCommand.Items)); }
public Snapshot CreateSnapshot(IAggregateRoot aggregateRoot) { if (aggregateRoot == null) { throw new ArgumentNullException("aggregateRoot"); } var payload = _binarySerializer.Serialize(aggregateRoot); var aggregateRootTypeCode = _aggregateRootTypeCodeProvider.GetTypeCode(aggregateRoot.GetType()); return(new Snapshot(aggregateRootTypeCode, aggregateRoot.UniqueId, aggregateRoot.Version, payload, DateTime.Now)); }
public Snapshot CreateSnapshot(IAggregateRoot aggregateRoot) { if (aggregateRoot == null) { throw new ArgumentNullException("aggregateRoot"); } var payload = _binarySerializer.Serialize(aggregateRoot); var aggregateRootTypeCode = _aggregateRootTypeCodeProvider.GetTypeCode(aggregateRoot.GetType()); return new Snapshot(aggregateRootTypeCode, aggregateRoot.UniqueId, aggregateRoot.Version, payload, DateTime.Now); }
private static Dictionary <string, object> PrepareHeaders(IAggregateRoot aggregate, Action <IDictionary <string, object> > updateHeaders) { var headers = new Dictionary <string, object> (); headers[AggregateTypeHeader] = aggregate.GetType().FullName; if (updateHeaders != null) { updateHeaders(headers); } return(headers); }
public async Task TakeSnapshotSync(IAggregateRoot aggregate) { if (!(aggregate is ISnapshotable)) { return; } var takeSnapshotMethod = aggregate.GetType().GetMethod("TakeSnapshot"); var memento = (Memento)takeSnapshotMethod.Invoke(aggregate, new object[] { }); await snapshotStore.Write(memento); }
private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = _aggregateSnapshotter.RestoreFromSnapshot(aggregateRootType, aggregateRootId); if (aggregateRoot == null) return false; if (aggregateRoot.GetType() != aggregateRootType || aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("AggregateRoot recovery from snapshot is invalid as the aggregateRootType or aggregateRootId is not matched. Snapshot: [aggregateRootType:{0},aggregateRootId:{1}], expected: [aggregateRootType:{2},aggregateRootId:{3}]", aggregateRoot.GetType(), aggregateRoot.UniqueId, aggregateRootType, aggregateRootId)); } var aggregateRootTypeName = _typeNameProvider.GetTypeName(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeName, aggregateRoot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return true; }
public IAggregateRoot Remove(IAggregateRoot aggregate) { if (aggregate == null) { return(null); } var key = this.CacheKey(aggregate.GetType(), aggregate.Id); var result = this._memoryCache.Get <IAggregateRoot>(key); this._memoryCache.Remove(key); return(result); }
private void PublishEvents(IAggregateRoot instance, IDomainNotification snapshotChange) { foreach (var evt in instance.UncommittedEvents.ToList()) { var modelChange = NotificationExtensions.CreateNotification(instance.GetType(), evt); this.changes.OnNext(modelChange); } if (snapshotChange != null) { this.changes.OnNext(snapshotChange); } }
public static bool ShouldMakeSnapshot(IAggregateRoot aggregate) { if (!IsSnapshotable(aggregate.GetType())) { return(false); } if (aggregate.Version != 0 && aggregate.Version % _snapshotInterval == 0) { return(true); } return(false); }
internal static void Apply(IAggregateRoot root, IDomainEvent ev) { var rootType = root.GetType(); EventHandlerRegistry registry; if (!_handlers.TryGetValue(rootType, out registry)) { registry = new EventHandlerRegistry(ApplyMethodResolver.ResolveAll(rootType)); _handlers[rootType] = registry; } registry.Handle(root, ev); //ResolveApplyMethodDelegate(root.GetType(), ev.GetType())(root, ev); }
private static string CreateMessage(IAggregateRoot aggRoot, Guid originalVersion, Guid currentVersion) { var aggType = aggRoot.GetType().Name; var msg = string.Format("The {0} you were trying to save has been updated by another user, you will have to start the editing process again to retry.", aggType); msg += Environment.NewLine; msg += Environment.NewLine; msg += "Aggregate ID: " + aggRoot.AggregateId.ToString(); msg += Environment.NewLine; msg += "Original Version: " + originalVersion.ToString(); msg += Environment.NewLine; msg += "Current Version: " + currentVersion.ToString(); return msg; }
public ConcurrencyException(IAggregateRoot aggregate) : base(string.Format("Two different versions of aggregate root {0} of type '{1}' was detected in one DataSession", ((IEntity) aggregate).IdObject, aggregate.GetType().Name)) { Aggregate = aggregate; }
private void IncreaseAggregateVersion(IAggregateRoot aggregateRoot) { _increaseVersionMethodDict[aggregateRoot.GetType()](aggregateRoot); }
private void HandleEvent(IAggregateRoot aggregateRoot, IDomainEvent evnt) { var handler = _eventHandlerProvider.GetInternalEventHandler(aggregateRoot.GetType(), evnt.GetType()); if (handler == null) { throw new ENodeException("Could not find event handler for [{0}] of [{1}]", evnt.GetType().FullName, aggregateRoot.GetType().FullName); } handler(aggregateRoot, evnt); }
private EventStream CreateEventStream(IAggregateRoot aggregateRoot, ICommand command) { var uncommittedEvents = aggregateRoot.GetUncommittedEvents().ToList(); aggregateRoot.ClearUncommittedEvents(); var aggregateRootTypeCode = _aggregateRootTypeProvider.GetTypeCode(aggregateRoot.GetType()); foreach (var evnt in uncommittedEvents) { evnt.Version = aggregateRoot.Version + 1; } return new EventStream( command.Id, aggregateRoot.UniqueId, aggregateRootTypeCode, aggregateRoot.Version + 1, DateTime.Now, uncommittedEvents); }
public ConcurrencyException(IAggregateRoot root, IDomainEvent conflictEvent) : base(string.Format("Expected version of {0}({1}) to be {2} but got {3}." , root.GetType().Name, root.Id, root.Version, conflictEvent.Version)) { }
///<summary> /// 将一个FisObject注册为Added ///</summary> ///<param name="entity">fisobject</param> ///<param name="repository">该FisObject类型的Repository对象</param> public void RegisterAdded(IAggregateRoot entity, IUnitOfWorkRepository repository) { if (!this._added.ContainsKey(entity)) { logger.DebugFormat(MsgRegisterAdded, entity.GetType(), entity.Key); this._added.Add(entity, repository); _execSeq.Add(entity); } }