/// <summary> /// Retrieve the aggregate of the specified <paramref name="aggregateType"/> and aggregate <paramref name="id"/>. /// </summary> /// <param name="aggregateType">The type of aggregate to retrieve.</param> /// <param name="id">The unique aggregate id.</param> public Aggregate Get(Type aggregateType, Guid id) { Aggregate aggregate; InvokePreGetHooks(aggregateType, id); aggregate = aggregateStore.Get(aggregateType, id); InvokePostGetHooks(aggregate); return(aggregate); }
/// <summary> /// Gets or creates an aggregate of type <typeparamref name="TAggregate"/> identified by <paramref name="id"/>. /// </summary> /// <typeparam name="TAggregate">The type of aggregate to retrieve or create.</typeparam> /// <param name="aggregateStore">The aggregate store to extend.</param> /// <param name="id">The unique aggregate id.</param> /// <param name="initializer">The aggregate initializer.</param> public static TAggregate GetOrCreate <TAggregate>(this IStoreAggregates aggregateStore, Guid id, Action <TAggregate> initializer) where TAggregate : Aggregate { Verify.NotNull(aggregateStore, nameof(aggregateStore)); Verify.NotNull(initializer, nameof(initializer)); var aggregate = aggregateStore.Get <TAggregate>(id); if (aggregate.Version > 0) { return(aggregate); } return(aggregateStore.Create(aggregate, initializer)); }
/// <summary> /// Creates an aggregate of type <typeparamref name="TAggregate"/> identified by <paramref name="id"/> if does not already exist; otherwise throws an <see cref="InvalidOperationException"/>. /// </summary> /// <typeparam name="TAggregate">The type of aggregate to retrieve.</typeparam> /// <param name="aggregateStore">The aggregate repository from which the aggregate is to be retrieved.</param> /// <param name="id">The unique aggregate id.</param> /// <param name="initializer">The aggregate initializer.</param> public static TAggregate Create <TAggregate>(this IStoreAggregates aggregateStore, Guid id, Action <TAggregate> initializer) where TAggregate : Aggregate { Verify.NotNull(aggregateStore, nameof(aggregateStore)); Verify.NotNull(initializer, nameof(initializer)); var aggregate = aggregateStore.Get <TAggregate>(id); if (aggregate.Version > 0) { throw new InvalidOperationException(Exceptions.AggregateAlreadyExists.FormatWith(typeof(TAggregate), id)); } return(aggregateStore.Create(aggregate, initializer)); }
/// <summary> /// Invokes the underlying <see cref="Aggregate"/> command handler method for <see cref="Command"/>. /// </summary> /// <param name="context">The current command context.</param> public void Handle(CommandContext context) { var command = context.Command; var aggregate = aggregateStore.Get(AggregateType, context.AggregateId); Log.Trace("Executing {0} command on aggregate {1}", command, aggregate); aggregate.VerifyCanHandleCommand(command); executor(aggregate, command); if (context.HasRaisedEvents) { aggregateStore.Save(aggregate, context); } else { Log.Warn("Executing {0} command on aggregate {1} raised no events", command, aggregate); } }
/// <summary> /// Retrieve the aggregate of the specified <paramref name="aggregateType"/> and aggregate <paramref name="id"/>. /// </summary> /// <param name="aggregateType">The type of aggregate to retrieve.</param> /// <param name="id">The unique aggregate id.</param> public Aggregate Get(Type aggregateType, Guid id) { Verify.NotNull(aggregateType, nameof(aggregateType)); var key = String.Concat(aggregateType.GetFullNameWithAssembly(), "-", id); using (var aggregateLock = new AggregateLock(aggregateType, id)) { aggregateLock.Aquire(); //NOTE: We do not want to use AddOrGetExisting due to internal global cache lock while doing aggregate lookup. var aggregate = (Aggregate)memoryCache.Get(key); if (aggregate == null) { memoryCache.Add(key, aggregate = aggregateStore.Get(aggregateType, id), CreateCacheItemPolicy()); } //NOTE: Given that aggregate state is only applied during `Save`, we can return the cached instance. // This avoids making a copy of the aggregate when no state changes will be applied. return(aggregate); } }