private void SaveFunc(TEventSourced aggregate)
        {
            // Avoid to add a largest number of events one shot. If you need to store more then 'Largest' events,
            // split the operation in two or more 'save' operation to keep stream size smaller, and allow
            // to create automatically one or more snapshot of the aggregate to drive the system
            // in performance optimization as result.
            if (aggregate.Changes.Count >= Largest)
            {
                throw new DomainEventsToAddLimitException($"If you need to store more then '{Largest}' events, " +
                                                          "split the operation in two or more 'save' operations to " +
                                                          "keep stream size smaller and allow to create automatically " +
                                                          "one or more snapshots");
            }

            var streamName = StreamNameFor(aggregate.Id);

            _eventStore.AppendEventsToStream(streamName, aggregate.Changes, aggregate.Version);

            // Get the stream size
            var streamSize = (int)_eventStore.GetEventsStreamSize(streamName);

            // Get the latest snapshot version
            var snapshot = _eventStore.GetLatestSnapshot(streamName);

            // Evaluate if snapshot creation is needed (after 'Largest' events stored)
            if ((streamSize - (snapshot?.Version ?? 0)) >= Largest)
            {
                MakeASnapshot(aggregate.Id);
            }
        }
Exemple #2
0
        /// <summary>
        /// Saves the specified Product.
        /// </summary>
        /// <param name="Product">The Product.</param>
        public void Save(Product Product)
        {
            var streamName      = StreamNameFor(Product.Id);
            var expectedVersion = GetExpectedVersion(Product.InitialVersion);

            _eventStore.AppendEventsToStream(streamName, Product.Changes, expectedVersion);
        }
        /// <summary>
        /// Saves the specified cart.
        /// </summary>
        /// <param name="cart">The cart.</param>
        public void Save(Cart cart)
        {
            var streamName      = StreamNameFor(cart.Id);
            var expectedVersion = GetExpectedVersion(cart.InitialVersion);

            _eventStore.AppendEventsToStream(streamName, cart.Changes, expectedVersion);
        }
Exemple #4
0
        /// <summary>
        /// Saves the specified order.
        /// </summary>
        /// <param name="order">The order.</param>
        public void Save(Order order)
        {
            var streamName      = StreamNameFor(order.Id);
            var expectedVersion = GetExpectedVersion(order.InitialVersion);

            _eventStore.AppendEventsToStream(streamName, order.Changes, expectedVersion);
        }
Exemple #5
0
        /// <summary>
        /// Saves the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        public void Save(TEntity entity)
        {
            var streamName      = StreamNameFor(entity.Id);
            var expectedVersion = GetExpectedVersion(Convert.ToInt32(entity.GetType().GetProperty("InitialVersion")));

            _eventStore.AppendEventsToStream(streamName, entity.Changes, expectedVersion);
        }
        public void Save(Customer customer)
        {
            var streamName = StreamNameFor(customer.Id);

            // TODO Implement once snapshots are available
            //var expectedVersion = GetExpectedVersion(customer.InitialVersion);
            _eventStore.AppendEventsToStream(streamName, customer.Changes, null);
        }
Exemple #7
0
        public void Save(BankAccount bankAccount)
        {
            var streamName = StreamFor(bankAccount.Id);

            var expectedVersion = GetExpectedVersion(bankAccount.LastStoredEventNumber);

            _eventStore.AppendEventsToStream(streamName, bankAccount.Changes, expectedVersion);
        }
Exemple #8
0
        public void Save(PayAsYouGoAccount payAsYouGoAccount)
        {
            var streamName = StreamNameFor(payAsYouGoAccount.Id);

            var expectedVersion = GetExpectedVersion(payAsYouGoAccount.InitialVersion);

            _eventStore.AppendEventsToStream(streamName, payAsYouGoAccount.Changes, expectedVersion);
        }
        public async Task Update(TAggregate aggregate)
        {
            var streamName = StreamNameFor(aggregate.Id);

            //var expectedVersion = GetExpectedVersion(rit.InitialVersion);
            //_eventStore.AppendEventsToStream(streamName, rit.Changes, expectedVersion);
            _eventStore.AppendEventsToStream(streamName, aggregate.GetUncommittedEvents(), 0);
            aggregate.MarkEventsAsCommitted();
        }
        void Update(ICommand <SecurityId> c, Action <SecurityAggregate> action)
        {
            var eventStream = _eventStore.LoadEventStream(c.Id);
            var state       = new SecurityState(eventStream.Events);
            var agg         = new SecurityAggregate(state);

            action(agg);
            _eventStore.AppendEventsToStream(c.Id, eventStream.StreamVersion, agg.Changes);
        }
Exemple #11
0
        // lifetime change management

        // atomic consistency boundary of an Aggregate & its contents

        void UpdateDomain(Action <TrustedSystemAggregate> usingThisMethod)
        {
            if (_currentSystem == null)
            {
                throw new InvalidOperationException("System ID should be provided by now");
            }

            var eventStreamId = _currentSystem.ToStreamId();
            var eventStream   = _eventStore.LoadEventStream(eventStreamId);

            var aggStateBeforeChanges = TrustedSystemState.BuildStateFromEventHistory(eventStream.Events);

            var aggToChange = new TrustedSystemAggregate(aggStateBeforeChanges);


            usingThisMethod(aggToChange);

            _eventStore.AppendEventsToStream(eventStreamId, eventStream.StreamVersion, aggToChange.EventsCausingChanges);
        }
Exemple #12
0
        private void SaveAggregateEvents(TAggregate aggregate)
        {
            var changes = aggregate.GetUncommitedChanges();

            var streamName = StreamNameFor(aggregate);

            m_eventStore.AppendEventsToStream(streamName, changes);

            aggregate.MarkChangesAsCommited();
        }
Exemple #13
0
        void Update(ICommand<RegistrationId> c, Action<RegistrationAggregate> action)
        {
            var stream = _eventStore.LoadEventStream(c.Id);
            var state = new RegistrationState(stream.Events);
            var agg = new RegistrationAggregate(state);

            using (Context.CaptureForThread()) {
                action(agg);
                _eventStore.AppendEventsToStream(c.Id, stream.StreamVersion, agg.Changes);
            }
        }
        void Update(ICommand <UserId> c, Action <UserAggregate> action)
        {
            var stream = _store.LoadEventStream(c.Id);
            var state  = new UserState(stream.Events);
            var agg    = new UserAggregate(state);

            using (Context.CaptureForThread()) {
                agg.ThrowOnInvalidStateTransition(c);
                action(agg);
                _store.AppendEventsToStream(c.Id, stream.StreamVersion, agg.Changes);
            }
        }
        void Update(ICommand <FactoryId> c, Action <FactoryAggregate> execute)
        {
            // Load event stream from the store
            var eventStream = _eventStore.LoadEventStream(c.Id);
            // create new Factory aggregate from the history
            var state = new FactoryState(eventStream.Events);
            var agg   = new FactoryAggregate(state);

            // execute delegated action
            execute(agg);
            // append resulting changes to the stream
            _eventStore.AppendEventsToStream(c.Id, eventStream.StreamVersion, agg.Changes);
        }
Exemple #16
0
        // this Update method abstracts away the name of the exact aggregate method that we will be using/calling
        // this approach allows us to use this single Update method for multiple command messages
        // this method is where we implement the lifetime management of an Aggregate in one place

        void Update(ICommand <FactoryId> forAggregateIdentifiedBy, Action <FactoryAggregate> executeCommandUsingThis)
        {
            // Load the event stream from the event store using the FactoryId of the passed in command
            var eventStream = _eventStore.LoadEventStream(forAggregateIdentifiedBy.Id);

            // create a new Factory aggregate instance from its history of allEventsRelatedToThisAggregateId
            var aggregateState = new FactoryState(eventStream.Events);
            var aggregate      = new FactoryAggregate(aggregateState);

            // execute the delegated Action (lambda that contains a reference to a specific aggregate method call)
            // that was passed to this Update method by the "When" methods below
            executeCommandUsingThis(aggregate);

            // append resulting changes to the aggregate's event stream
            _eventStore.AppendEventsToStream(forAggregateIdentifiedBy.Id, eventStream.StreamVersion, aggregate.EventsThatHappened);
        }
Exemple #17
0
        // this Update method abstracts away the name of the exact aggregate method that we will be using/calling
        // this approach allows us to use this single Update method for multiple command messages
        // this method is where we implement the lifetime management of a FactoryAggregate in one place
        void Update(ICommand <FactoryId> c, Action <FactoryAggregate> execute)
        {
            // Load the event stream from the store using the FactoryId of the passed in command
            var eventStream = _eventStore.LoadEventStream(c.Id);

            // create a new Factory aggregate instance from its history of events
            var state = new FactoryState(eventStream.Events);
            var agg   = new FactoryAggregate(state);

            // execute the delegated Action (lambda that contains a reference to a specific method call)
            // that was passed to this Update method by the "When" methods below
            execute(agg);

            // append resulting changes to the aggregate state to the event stream
            _eventStore.AppendEventsToStream(c.Id, eventStream.StreamVersion, agg.Changes);
        }
Exemple #18
0
        // lifetime change management
        // atomic consistency boundary of an Aggregate & its contents
        void ChangeAgg(TrustedSystemId withAggIdOf, Action <TrustedSystemAggregate> usingThisMethod)
        {
            var eventStreamId = withAggIdOf.Id.ToString();
            var eventStream   = _eventStore.LoadEventStream(eventStreamId);

            var aggStateBeforeChanges = TrustedSystemState.BuildStateFromEventHistory(eventStream.Events);

            var aggToChange = new TrustedSystemAggregate(aggStateBeforeChanges);

            // HACK
            if (eventStream.Events.Count == 0)
            {
                aggToChange.Create(withAggIdOf);
            }

            usingThisMethod(aggToChange);

            _eventStore.AppendEventsToStream(eventStreamId, eventStream.StreamVersion, aggToChange.EventsCausingChanges);
        }