/// <summary>
        /// Save the specified <paramref name="context"/> changes for the given aggregate.
        /// </summary>
        /// <param name="aggregate">The current aggregate version for which the context applies.</param>
        /// <param name="context">The command context containing the aggregate changes to be applied.</param>
        public SaveResult Save(Aggregate aggregate, CommandContext context)
        {
            Verify.NotNull(aggregate, nameof(aggregate));
            Verify.NotNull(context, nameof(context));

            var copy          = aggregate.Copy();
            var aggregateType = aggregate.GetType();
            var key           = String.Concat(aggregateType.GetFullNameWithAssembly(), "-", aggregate.Id);

            using (var aggregateLock = new AggregateLock(aggregateType, aggregate.Id))
            {
                aggregateLock.Aquire();

                try
                {
                    var result = aggregateStore.Save(copy, context);

                    memoryCache.Set(key, copy, CreateCacheItemPolicy());

                    return(result);
                }
                catch (ConcurrencyException)
                {
                    memoryCache.Remove(key);
                    throw;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the set of known apply methods for the given <paramref name="aggregate"/> instance.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance on which the event is to be applied.</param>
        private ApplyMethodCollection GetKnownApplyMethods(Aggregate aggregate)
        {
            Type aggregateType = aggregate.GetType();
            ApplyMethodCollection applyMethods;

            if (!knownApplyMethods.TryGetValue(aggregateType, out applyMethods))
            {
                throw new MappingException(Exceptions.AggregateTypeUndiscovered.FormatWith(aggregate.GetType()));
            }

            return(applyMethods);
        }
Пример #3
0
        /// <summary>
        /// Creates a commit for the specified <paramref name="aggregate"/> based on the provided <paramref name="context"/>.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance for which the commit is to be applied.</param>
        /// <param name="context">The <see cref="CommandContext"/> instance containing the pending modifications to the associated <paramref name="aggregate"/>.</param>
        private static Commit CreateCommit(Aggregate aggregate, CommandContext context)
        {
            EventCollection  events = context.GetRaisedEvents();
            HeaderCollection headers;

            if (aggregate.Version == 0)
            {
                var typeHeader = new Header(Header.Aggregate, aggregate.GetType().GetFullNameWithAssembly(), checkReservedNames: false);

                headers = new HeaderCollection(context.Headers.Concat(typeHeader));
            }
            else
            {
                headers = context.Headers;
            }

            return(new Commit(context.CommandId, aggregate.Id, aggregate.Version + 1, headers, events));
        }
        /// <summary>
        /// Save the specified <paramref name="context"/> changes for the given aggregate.
        /// </summary>
        /// <param name="aggregate">The current aggregate version for which the context applies.</param>
        /// <param name="context">The command context containing the aggregate changes to be applied.</param>
        public SaveResult Save(Aggregate aggregate, CommandContext context)
        {
            Verify.NotNull(aggregate, nameof(aggregate));
            Verify.NotNull(context, nameof(context));

            var copy = aggregate.Copy();
            var aggregateType = aggregate.GetType();
            var key = String.Concat(aggregateType.GetFullNameWithAssembly(), "-", aggregate.Id);
            using (var aggregateLock = new AggregateLock(aggregateType, aggregate.Id))
            {
                aggregateLock.Aquire();

                try
                {
                    var result = aggregateStore.Save(copy, context);

                    memoryCache.Set(key, copy, CreateCacheItemPolicy());

                    return result;
                }
                catch (ConcurrencyException)
                {
                    memoryCache.Remove(key);
                    throw;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Get the associated apply method for the specified <see cref="Event"/> <paramref name="e"/> from the known <paramref name="applyMethods"/>.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance on which the event is to be applied.</param>
        /// <param name="e">The <see cref="Event"/> to be applied.</param>
        /// <param name="applyMethods">The set of known apply methods for a given aggregate instance</param>
        private static Action <Aggregate, Event> GetApplyMethod(Aggregate aggregate, Event e, ApplyMethodCollection applyMethods)
        {
            Action <Aggregate, Event> applyMethod;
            Type eventType = e.GetType();

            if (applyMethods.TryGetValue(eventType, out applyMethod))
            {
                return(applyMethod);
            }

            if (!applyMethods.ApplyOptional)
            {
                throw new MappingException(Exceptions.AggregateApplyMethodNotFound.FormatWith(aggregate.GetType(), e.GetType()));
            }

            return(VoidApplyMethod);
        }
        /// <summary>
        /// Gets the set of known apply methods for the given <paramref name="aggregate"/> instance.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance on which the event is to be applied.</param>
        private ApplyMethodCollection GetKnownApplyMethods(Aggregate aggregate)
        {
            Type aggregateType = aggregate.GetType();
            ApplyMethodCollection applyMethods;

            if (!knownApplyMethods.TryGetValue(aggregateType, out applyMethods))
                throw new MappingException(Exceptions.AggregateTypeUndiscovered.FormatWith(aggregate.GetType()));

            return applyMethods;
        }
        /// <summary>
        /// Get the associated apply method for the specified <see cref="Event"/> <paramref name="e"/> from the known <paramref name="applyMethods"/>.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance on which the event is to be applied.</param>
        /// <param name="e">The <see cref="Event"/> to be applied.</param>
        /// <param name="applyMethods">The set of known apply methods for a given aggregate instance</param>
        private static Action<Aggregate, Event> GetApplyMethod(Aggregate aggregate, Event e, ApplyMethodCollection applyMethods)
        {
            Action<Aggregate, Event> applyMethod;
            Type eventType = e.GetType();

            if (applyMethods.TryGetValue(eventType, out applyMethod))
                return applyMethod;

            if (!applyMethods.ApplyOptional)
                throw new MappingException(Exceptions.AggregateApplyMethodNotFound.FormatWith(aggregate.GetType(), e.GetType()));

            return VoidApplyMethod;
        }
        /// <summary>
        /// Creates a commit for the specified <paramref name="aggregate"/> based on the provided <paramref name="context"/>.
        /// </summary>
        /// <param name="aggregate">The <see cref="Aggregate"/> instance for which the commit is to be applied.</param>
        /// <param name="context">The <see cref="CommandContext"/> instance containing the pending modifications to the associated <paramref name="aggregate"/>.</param>
        private static Commit CreateCommit(Aggregate aggregate, CommandContext context)
        {
            EventCollection events = context.GetRaisedEvents();
            HeaderCollection headers;

            if (aggregate.Version == 0)
            {
                var typeHeader = new Header(Header.Aggregate, aggregate.GetType().GetFullNameWithAssembly(), checkReservedNames: false);

                headers = new HeaderCollection(context.Headers.Concat(typeHeader));
            }
            else
            {
                headers = context.Headers;
            }

            return new Commit(context.CommandId, aggregate.Id, aggregate.Version + 1, headers, events);
        }