|
|
|
@ -10,6 +10,9 @@ using System; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using Squidex.Infrastructure.CQRS.Events; |
|
|
|
|
|
|
|
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
|
|
|
|
// ReSharper disable InvertIf
|
|
|
|
|
|
|
|
namespace Squidex.Infrastructure.CQRS.Commands |
|
|
|
{ |
|
|
|
public sealed class AggregateHandler : IAggregateHandler |
|
|
|
@ -17,16 +20,6 @@ namespace Squidex.Infrastructure.CQRS.Commands |
|
|
|
private readonly IDomainObjectRepository domainObjectRepository; |
|
|
|
private readonly IDomainObjectFactory domainObjectFactory; |
|
|
|
|
|
|
|
public IDomainObjectRepository Repository |
|
|
|
{ |
|
|
|
get { return domainObjectRepository; } |
|
|
|
} |
|
|
|
|
|
|
|
public IDomainObjectFactory Factory |
|
|
|
{ |
|
|
|
get { return domainObjectFactory; } |
|
|
|
} |
|
|
|
|
|
|
|
public AggregateHandler( |
|
|
|
IDomainObjectFactory domainObjectFactory, |
|
|
|
IDomainObjectRepository domainObjectRepository) |
|
|
|
@ -38,44 +31,58 @@ namespace Squidex.Infrastructure.CQRS.Commands |
|
|
|
this.domainObjectRepository = domainObjectRepository; |
|
|
|
} |
|
|
|
|
|
|
|
public async Task<T> CreateAsync<T>(CommandContext context, Func<T, Task> creator) where T : class, IAggregate |
|
|
|
public Task<T> 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 = domainObjectFactory.CreateNew<T>(aggregateCommand.AggregateId); |
|
|
|
|
|
|
|
await creator(aggregate); |
|
|
|
|
|
|
|
await SaveAsync(aggregate); |
|
|
|
return InvokeAsync(context, creator, false); |
|
|
|
} |
|
|
|
|
|
|
|
if (!context.IsCompleted) |
|
|
|
{ |
|
|
|
context.Complete(new EntityCreatedResult<Guid>(aggregate.Id, aggregate.Version)); |
|
|
|
} |
|
|
|
public Task<T> UpdateAsync<T>(CommandContext context, Func<T, Task> updater) where T : class, IAggregate |
|
|
|
{ |
|
|
|
Guard.NotNull(updater, nameof(updater)); |
|
|
|
|
|
|
|
return aggregate; |
|
|
|
return InvokeAsync(context, updater, true); |
|
|
|
} |
|
|
|
|
|
|
|
public async Task<T> UpdateAsync<T>(CommandContext context, Func<T, Task> updater) where T : class, IAggregate |
|
|
|
private async Task<T> InvokeAsync<T>(CommandContext context, Func<T, Task> handler, bool isUpdate) where T : class, IAggregate |
|
|
|
{ |
|
|
|
Guard.NotNull(updater, nameof(updater)); |
|
|
|
Guard.NotNull(context, nameof(context)); |
|
|
|
|
|
|
|
var aggregateCommand = GetCommand(context); |
|
|
|
var aggregate = await domainObjectRepository.GetByIdAsync<T>(aggregateCommand.AggregateId, aggregateCommand.ExpectedVersion); |
|
|
|
var aggregateObject = domainObjectFactory.CreateNew<T>(aggregateCommand.AggregateId); |
|
|
|
|
|
|
|
await updater(aggregate); |
|
|
|
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()); |
|
|
|
|
|
|
|
await SaveAsync(aggregate); |
|
|
|
aggregateObject.ClearUncommittedEvents(); |
|
|
|
|
|
|
|
if (!context.IsCompleted) |
|
|
|
{ |
|
|
|
context.Complete(new EntitySavedResult(aggregate.Version)); |
|
|
|
if (isUpdate) |
|
|
|
{ |
|
|
|
context.Complete(new EntitySavedResult(aggregateObject.Version)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
context.Complete(EntityCreatedResult.Create(aggregateObject.Id, aggregateObject.Version)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return aggregate; |
|
|
|
return aggregateObject; |
|
|
|
} |
|
|
|
|
|
|
|
private static IAggregateCommand GetCommand(CommandContext context) |
|
|
|
@ -91,19 +98,5 @@ namespace Squidex.Infrastructure.CQRS.Commands |
|
|
|
|
|
|
|
return command; |
|
|
|
} |
|
|
|
|
|
|
|
private async Task SaveAsync(IAggregate aggregate) |
|
|
|
{ |
|
|
|
var events = aggregate.GetUncomittedEvents(); |
|
|
|
|
|
|
|
foreach (var @event in events) |
|
|
|
{ |
|
|
|
@event.SetAggregateId(aggregate.Id); |
|
|
|
} |
|
|
|
|
|
|
|
await domainObjectRepository.SaveAsync(aggregate, events, Guid.NewGuid()); |
|
|
|
|
|
|
|
aggregate.ClearUncommittedEvents(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|