public async Task <TDomainObject> GetByIdAsync <TDomainObject>(Guid id, long?expectedVersion = null) where TDomainObject : class, IAggregate
        {
            var streamName = nameResolver.GetStreamName(typeof(TDomainObject), id);

            var events = await eventStore.GetEventsAsync(streamName).ToList();

            if (events.Count == 0)
            {
                throw new DomainObjectNotFoundException(id.ToString(), typeof(TDomainObject));
            }

            var domainObject = (TDomainObject)factory.CreateNew(typeof(TDomainObject), id);

            foreach (var storedEvent in events)
            {
                var envelope = ParseOrNull(storedEvent);

                if (envelope != null)
                {
                    domainObject.ApplyEvent(envelope);
                }
            }

            if (expectedVersion != null && domainObject.Version != expectedVersion.Value)
            {
                throw new DomainObjectVersionException(id.ToString(), typeof(TDomainObject), domainObject.Version, expectedVersion.Value);
            }

            return(domainObject);
        }
Example #2
0
        public DefaultDomainObjectRepositoryTests()
        {
            domainObject = new MyDomainObject(aggregateId, 123);

            A.CallTo(() => nameResolver.GetStreamName(A <Type> .Ignored, aggregateId))
            .Returns(streamName);

            A.CallTo(() => factory.CreateNew <MyDomainObject>(aggregateId))
            .Returns(domainObject);

            sut = new DefaultDomainObjectRepository(eventStore, nameResolver, formatter);
        }
        public async Task Create_async_should_create_domain_object_and_save()
        {
            A.CallTo(() => factory.CreateNew <MyDomainObject>(domainObject.Id))
            .Returns(domainObject);

            A.CallTo(() => repository.SaveAsync(domainObject, A <ICollection <Envelope <IEvent> > > .Ignored, A <Guid> .Ignored))
            .Returns(TaskHelper.Done);

            MyDomainObject passedDomainObject = null;

            await sut.CreateAsync <MyDomainObject>(context, async x =>
            {
                await Task.Delay(1);

                passedDomainObject = x;
            });

            Assert.Equal(domainObject, passedDomainObject);
            Assert.NotNull(context.Result <EntityCreatedResult <Guid> >());

            A.CallTo(() => repository.SaveAsync(domainObject, A <ICollection <Envelope <IEvent> > > .Ignored, A <Guid> .Ignored)).MustHaveHappened();
        }
Example #4
0
        public async Task CreateAsync <T>(CommandContext context, Func <T, Task> creator) where T : class, IAggregate
        {
            Guard.NotNull(creator, nameof(creator));
            Guard.NotNull(context, nameof(context));

            var aggregateCommand = GetCommand(context);
            var aggregate        = (T)domainObjectFactory.CreateNew(typeof(T), aggregateCommand.AggregateId);

            await creator(aggregate);

            await SaveAsync(aggregate);

            if (!context.IsHandled)
            {
                context.Succeed(new EntityCreatedResult <Guid>(aggregate.Id, aggregate.Version));
            }
        }
Example #5
0
        private async Task <T> InvokeAsync <T>(CommandContext context, Func <T, Task> handler, bool isUpdate) where T : class, IAggregate
        {
            Guard.NotNull(context, nameof(context));

            var aggregateCommand = GetCommand(context);
            var aggregateObject  = domainObjectFactory.CreateNew <T>(aggregateCommand.AggregateId);

            if (isUpdate)
            {
                await domainObjectRepository.LoadAsync(aggregateObject, aggregateCommand.ExpectedVersion);
            }

            await handler(aggregateObject);

            var events = aggregateObject.GetUncomittedEvents();

            foreach (var @event in events)
            {
                @event.SetAggregateId(aggregateObject.Id);
            }

            await domainObjectRepository.SaveAsync(aggregateObject, events, Guid.NewGuid());

            aggregateObject.ClearUncommittedEvents();

            if (!context.IsCompleted)
            {
                if (isUpdate)
                {
                    context.Complete(new EntitySavedResult(aggregateObject.Version));
                }
                else
                {
                    context.Complete(EntityCreatedResult.Create(aggregateObject.Id, aggregateObject.Version));
                }
            }

            return(aggregateObject);
        }