예제 #1
0
 public CommandScheduler(
     IEventSourcedRepository <TAggregate> repository,
     ICommandPreconditionVerifier preconditionVerifier = null)
 {
     if (repository == null)
     {
         throw new ArgumentNullException("repository");
     }
     this.repository           = repository;
     this.preconditionVerifier = preconditionVerifier ??
                                 Configuration.Current.Container.Resolve <ICommandPreconditionVerifier>();
 }
예제 #2
0
        public static async Task ApplyScheduledCommand <TAggregate>(
            this IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            ICommandPreconditionVerifier preconditionVerifier = null)
            where TAggregate : class, IEventSourced
        {
            TAggregate aggregate = null;
            Exception  exception = null;

            if (scheduled.Result is CommandDelivered)
            {
                return;
            }

            try
            {
                if (preconditionVerifier != null &&
                    !await preconditionVerifier.IsPreconditionSatisfied(scheduled))
                {
                    await FailScheduledCommand(repository,
                                               scheduled,
                                               new PreconditionNotMetException(scheduled.DeliveryPrecondition));

                    return;
                }

                aggregate = await repository.GetLatest(scheduled.AggregateId);

                if (aggregate == null)
                {
                    if (scheduled.Command is ConstructorCommand <TAggregate> )
                    {
                        var ctor = typeof(TAggregate).GetConstructor(new[] { scheduled.Command.GetType() });
                        aggregate = (TAggregate)ctor.Invoke(new[] { scheduled.Command });
                    }
                    else
                    {
                        // TODO: (ApplyScheduledCommand) this should probably be a different exception type.
                        throw new ConcurrencyException(
                                  string.Format("No {0} was found with id {1} so the command could not be applied.",
                                                typeof(TAggregate).Name, scheduled.AggregateId),
                                  new IEvent[] { scheduled });
                    }
                }
                else
                {
                    await aggregate.ApplyAsync(scheduled.Command);
                }

                await repository.Save(aggregate);

                scheduled.Result = new CommandSucceeded(scheduled);

                return;
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            await FailScheduledCommand(repository, scheduled, exception, aggregate);
        }