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>(); }
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); }