예제 #1
0
        /// <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);
        }
예제 #3
0
 public static void Apply <T>(this IAggregate <T> aggregate, IEnumerable <IEvent> events)
 {
     foreach (var @event in events)
     {
         aggregate.Apply(@event);
     }
 }
예제 #4
0
        // 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);
            }
        }
예제 #5
0
        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);
                }
            }
        }