/// <summary> /// Retrieves current state using snapshot and events /// </summary> /// <returns></returns> public async Task Restore() { // short-circuit if aggregate was created in this instance(there won't be any snapshots or events in db) if (_isNewDbAggregate) { return; } // get snapshot and events var(snapshot, events) = await _repository.GetSnapshotAndEvents( _aggregateName, AggregateId ); // apply snapshot if any if (snapshot != null) { // store aggregate version number _aggregateVersion = snapshot.AggregateVersion; // set snapshot as state _aggregate.State = JsonSerializer.Deserialize <TState>(snapshot.Data); } // apply events foreach (var dbEvent in events) { var @event = (TEvent)EventSerializer.DeserializeEvent(dbEvent); _aggregate.Apply(@event); // store aggregate version number _aggregateVersion = dbEvent.AggregateVersion; } }
public T Create <T>(Guid aggregateId, object[] events) where T : IAggregate { IAggregate aggregate = null; aggregate = (T)Activator.CreateInstance(typeof(T), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, new object[] { aggregateId }, null); aggregate.Id = aggregateId; if (events != null) { foreach (var @event in events) { aggregate.Apply(@event); } } return((T)aggregate); }
public static void Apply <T>(this IAggregate <T> aggregate, IEnumerable <IEvent> events) { foreach (var @event in events) { aggregate.Apply(@event); } }
// init method public async Task Init() { // get current state var(currentState, pendingEvents) = await GetCurrentStateAndPendingEvents(); // set aggregate state _aggregate.State = currentState; // if there are pending events apply them if (pendingEvents != null && pendingEvents.Length > 0) { // apply each event foreach (var dbEvent in pendingEvents) { _aggregate.Apply(dbEvent); } // persist updated state await PersistState(_aggregate.State); } }
public void handle(TIdentity?id, ICommand <TState> command, Action <IEnumerable <EventInfo <TIdentity, TState> > > success, Action <Exception> failure) { if (null == id) { try { var evts = _aggregate.Exec(_aggregate.Zero, command); var newId = _generator.Generate(); var newEvents = evts.Zip(Enumerable.Range(0, evts.Count), (ev, v) => EventInfo <TIdentity, TState> .NewBuilder(ev, newId, v).Build()); success.Invoke(newEvents); } catch (Exception e) { failure.Invoke(e); } } else { try { _eventStore.load(id.Value, (evts => { var state = evts.OrderBy(x => x.Version) .Select(x => x.Event) .Aggregate(_aggregate.Zero, (r, e) => _aggregate.Apply(r, e)); var lastVer = evts.Last().Version; var results = _aggregate.Exec(state, command); var infos = results.Zip(Enumerable.Range(lastVer + 1, lastVer + results.Count), (e, v) => EventInfo <TIdentity, TState> .NewBuilder(e, id.Value, v).Build()); success.Invoke(infos); }), failure); } catch (Exception e) { failure.Invoke(e); } } }