예제 #1
0
        public async Task CanAddMultipleDomainEventsToSingleEventProviderConcurrentlyWithConcurrencyExceptionAsync(int i)
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), i);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            await Repository.CommitAsync(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = await Repository.GetByIdentityAsync(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);

            var dispatcher = new CommandDispatcher(new CommandHandlerFactory(new CommandCatalog(new List <ICommandEntry> {
                new StaticCommandEntry(typeof(Deposit), new AggregateRootCommandHandler <AccountAggregateRoot, Deposit>(Repository))
            })), new CommandHandlerContextFactory(MetaFactories));

            var tasks = new Task[30];

            for (var j = 0; j < 30; j++)
            {
                tasks[j] = dispatcher.DispatchAsync(new Deposit(account.Identity, j));
            }
            ;

            try
            {
                Task.WaitAll(tasks);
            }
            catch (Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
예제 #2
0
        public virtual void CanAddMultipleDomainEventsToSingleEventProviderConcurrentlyAsync(int i)
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), i);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            Repository.Commit(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = Repository.GetByIdentity(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);
            var ch = new SynchronizedAggregateRootCommandHandler <AccountAggregateRoot, Deposit>(Repository, new AggregateRootSynchronizer(new AggregateRootSynchronizationCache()), new AggregateRootCache());

            var tasks = new Task[10];

            for (var j = 0; j < 10; j++)
            {
                tasks[j] = ch.HandleAsync(new CommandHandlerContext(new Deposit(account.Identity, j)));
            }

            try
            {
                Task.WaitAll(tasks);
            }
            catch (Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
        public override ICommandHandlingResult Handle(ICommandHandlerContext <Deposit> context)
        {
            var command = context.Command;

            Contract.Assume(command.Amount > decimal.Zero);

            var domainEvents = AccountAggregateRoot.Create(new Create(Guid.NewGuid(), 50));

            domainEvents.AggregateRoot.Execute(command);

            return(new CommandHandlingResult(command.CommandId));
        }
예제 #4
0
        public virtual async Task CanGetAggregateRootAsync(int i)
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), i);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            await Repository.CommitAsync(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = await Repository.GetByIdentityAsync(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);
        }
        public override void Handle(Deposit command)
        {
            Contract.Assume(command != null);
            Contract.Assume(command.Amount > decimal.Zero);

            var accountAggregate = new AccountAggregateRoot();

            var events = accountAggregate.Credit(command.Amount, new CanCreditAccount(CanCreditAccount));

            Contract.Assume(Contract.ForAll(events, o => o != null));

            _domainEventDispatcher.PublishAll(events);
        }
예제 #6
0
        public virtual ICommandHandlingResult CanGetAggregateRoot()
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), 100);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            var result = Repository.Commit(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = Repository.GetByIdentity(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);

            return(result);
        }
        private bool CanCreditAccount(AccountAggregateRoot account, decimal amount, out string declinationReason)
        {
            Contract.Requires(account != null);

            declinationReason = null;

            if (amount <= 0)
            {
                declinationReason = "Cannot credit an acount for $0.00.";
                return(false);
            }
            else if (account.Balance + amount > 100m)
            {
                declinationReason = "Account will be over $100 and fees will start to apply.";
                return(false);
            }

            return(true);
        }
예제 #8
0
        private bool CanDebitAccount(AccountAggregateRoot account, decimal amount, out string declinationReason)
        {
            Contract.Requires(account != null);

            declinationReason = null;

            if (amount <= 0)
            {
                declinationReason = "Cannot debit an acount for $0.00.";
                return(false);
            }
            else if (account.Overdrawn)
            {
                declinationReason = "Account is overdrawn.";
                return(false);
            }

            return(true);
        }
예제 #9
0
        public virtual void CanAddMultipleDomainEventsToSingleEventProviderConcurrentlyWithConcurrencyException()
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), 100);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            Repository.Commit(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = Repository.GetByIdentity(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);

            var dispatcher = new CommandDispatcher(new CommandHandlerFactory(new CommandCatalog(new List <ICommandEntry> {
                new StaticCommandEntry(typeof(Deposit), new AggregateRootCommandHandler <AccountAggregateRoot, Deposit>(Repository))
            })), new CommandHandlerContextFactory(MetaFactories));

            Parallel.For(0, 30, (i) =>
            {
                dispatcher.Dispatch(new Deposit(account.Identity, i));
            });
        }
예제 #10
0
        public virtual void CanAddMultipleDomainEventsToSingleEventProvider()
        {
            var command      = new Create(SequentialAtEndGuidGenerator.NewGuid(), 100);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            Repository.Commit(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var account = Repository.GetByIdentity(domainEvents.AggregateRoot.Identity);

            Assert.IsNotNull(account);

            var ch  = new AggregateRootCommandHandler <AccountAggregateRoot, Deposit>(Repository);
            var ch1 = new AggregateRootCommandHandler <AccountAggregateRoot, Withdraw>(Repository);

            var random = new Random();

            for (var i = 0; i < 15; i++)
            {
                ch.Handle(new CommandHandlerContext(new Deposit(account.Identity, i)));
                ch1.Handle(new CommandHandlerContext(new Withdraw(account.Identity, random.Next(1, 10) * i)));
            }
        }
예제 #11
0
        public virtual void CanAddMultipleDomainEventsToSingleEventProviderConcurrently()
        {
            var accountId    = SequentialAtEndGuidGenerator.NewGuid();
            var command      = new Create(accountId, 100);
            var domainEvents = AccountAggregateRoot.Create(command);

            domainEvents.AggregateRoot.State.ExternalStateTracker = GetStateTracker(domainEvents);

            Repository.Commit(new CommandHandlerContext(command), domainEvents.AggregateRoot as AccountAggregateRoot);

            var synchronizer       = new AggregateRootSynchronizer(new AggregateRootSynchronizationCache());
            var aggregateRootCache = new AggregateRootCache();

            var ch  = new SynchronizedAggregateRootCommandHandler <AccountAggregateRoot, Deposit>(Repository, synchronizer, aggregateRootCache);
            var ch1 = new SynchronizedAggregateRootCommandHandler <AccountAggregateRoot, Withdraw2>(Repository, synchronizer, aggregateRootCache);

            var random = new Random();

            Parallel.For(0, 20, (i) =>
            {
                ch.Handle(new CommandHandlerContext(new Deposit(accountId, i)));
                ch1.Handle(new CommandHandlerContext(new Withdraw2(accountId, random.Next(1, 10) * i)));
            });
        }
        public override ICommandHandlingResult Handle(ICommandHandlerContext <Create> context)
        {
            var domainEvents = AccountAggregateRoot.Create(context.Command);

            return(new CommandHandlingResult(context.Command.CommandId));
        }
 public GetCardAccountResponse(AccountAggregateRoot accountAggregateRoot)
 {
     Id      = accountAggregateRoot.Id;
     Balance = accountAggregateRoot.State.Balance;
     Issuer  = new IssuerReponseItem(accountAggregateRoot.State.IssuerId);
 }
예제 #14
0
 protected override void When() => Aggregate = Repository.GetByNaturalKey(AccountId);