Ejemplo n.º 1
0
        internal static void Perform <TCommand>(this IAggregateRoot aggregate, TCommand command)
        {
            var subscription = AggregateInvokersCache.GetWhenMethod(aggregate.GetType(), command.GetType());

            if (subscription == null)
            {
                throw new InvalidOperationException("Aggregate can't perform command.");
            }

            if (aggregate.Status == RootStatus.New && !subscription.IsConstructor)
            {
                throw new InvalidOperationException("Attempting to apply a command to non existed aggregate.");
            }

            if (aggregate.Status != RootStatus.New && subscription.IsConstructor)
            {
                throw new InvalidOperationException("Attempting to create existed aggregate.");
            }

            if (aggregate.Status == RootStatus.Archived)
            {
                throw new InvalidOperationException("Aggregate is archived.");
            }

            subscription.Invoker(aggregate, command);

            if (aggregate.Changes.Count < 1)
            {
                throw new InvalidOperationException($"Command '{command.GetType().AssemblyQualifiedName}' produced no events");
            }

            aggregate.Status = RootStatus.Alive;
            aggregate.Reel(aggregate.Changes);

            if (subscription.IsDestructor)
            {
                aggregate.Status = RootStatus.Archived;
            }
        }