public async Task AppendAsync( IAggregateId aggregateId, IReadOnlyList <IDomainEvent> domainEvents, long expectedVersion) { if (domainEvents.Count > 0) { var connection = await _connectionProvider.GrabConnection(); var results = await connection.ConditionalAppendToStreamAsync( aggregateId.ToStreamName(_eventStoreName), expectedVersion, domainEvents.Select(e => e.ToEventData())); switch (results.Status) { case ConditionalWriteStatus.Succeeded: break; case ConditionalWriteStatus.VersionMismatch: throw new VersionMismatchException(aggregateId.ToStreamName(_eventStoreName), expectedVersion); case ConditionalWriteStatus.StreamDeleted: throw new StreamDeletedException(aggregateId.ToStreamName(_eventStoreName)); default: throw new ArgumentOutOfRangeException(nameof(results.Status), results.Status.ToString()); } } }
public async Task <IReadOnlyList <IDomainEvent> > AsyncLoadAllEventsFor(IAggregateId aggregateId) { var connection = await _connectionProvider.GrabConnection(); var resolvedEvents = await connection.ReadAllStreamEventsForward(aggregateId.ToStreamName(_eventStoreName)); return(resolvedEvents.Select(e => e.Event.ToDomainEvent()).ToList()); }
public Task <Result <T> > Get <T>(IAggregateId aggregateId) where T : AggregateRoot, new() => _aggregateCache.TryFetch(aggregateId) .Unwrap( cachedAggregate => cachedAggregate.TryTakeValue <T>() .Unwrap( aggregate => Task.FromResult(Result.Ok(aggregate)), () => _store.Get <T>(aggregateId)), () => _store.Get <T>(aggregateId));
public TestCommand(IAggregateId id) { var c = Guid.NewGuid(); this.CorrelationId = c; this.CausationId = c; AggregateId = id; }
/// <summary> /// Retrieves existing aggregate from the store and executes the <see cref="aggregateTransformer"/> in /// order to pass some command to the aggregate. As a result of <see cref="aggregateTransformer"/> execution /// all changes of the aggregate will be persisted in the database. /// </summary> /// <param name="store"><see cref="IStore"/> instance which is used to transform the aggregate.</param> /// <param name="aggregateId">Unique ID of an aggregate.</param> /// <param name="aggregateTransformer">Generic transformer function that will be called if aggregate exists.</param> /// <returns>Returns success if aggregate has been found and transformer executed without errors.</returns> public static Task <Result> Borrow <T>( this IStore store, IAggregateId aggregateId, Func <T, Result <T> > aggregateTransformer) where T : AggregateRoot, new() { return(store.Borrow <T>(aggregateId, aggregate => Task.FromResult(aggregateTransformer(aggregate)))); }
/// <summary> /// Borrow method with async aggregate transformer. /// </summary> public static Task <Result> Borrow <T>( this IStore store, IAggregateId aggregateId, Func <T, Task <Result <T> > > aggregateTransformer) where T : AggregateRoot, new() => store.Get <T>(aggregateId) .OnSuccess(aggregateTransformer) .OnSuccess(aggregate => store.SaveChanges(aggregate)) .OnFailure( AggregateVersionMismatchError, () => store.Borrow(aggregateId, aggregateTransformer));
public static IEvent AddTestMetaData <TState>(this IEvent @event, IAggregateId id, int version = 0) { var(aggregateName, streamName) = typeof(TState).Name.AsStreamName(id); if (@event.Meta == null) { @event.Meta = new Dictionary <string, string>(); } @event.Tap(e => e.Meta.AddTypeInfo(e)); @event.Meta.AddMetaData(version, streamName, aggregateName, new TestCommand(id)); @event.Meta["test.statetype"] = typeof(TState).AssemblyQualifiedName; return(@event); }
public async Task <Result <T> > Get <T>(IAggregateId aggregateId) where T : AggregateRoot, new() { var domainEvents = await _eventStoreAppender.AsyncLoadAllEventsFor(aggregateId); if (domainEvents.Count > 0) { var aggregateRoot = ReconstructAggregateFrom <T>(domainEvents); return(Ok(aggregateRoot)); } return(Fail <T>(AggregateNotFoundInStore(aggregateId.Id))); }
public Task <Result <T> > Get <T>(IAggregateId aggregateId) where T : AggregateRoot, new() { if (!_domainEventsPerAggregate.TryGetValue(aggregateId.Id, out var domainEvents)) { return(Task.FromResult(Fail <T>(AggregateNotFoundInStore(aggregateId.Id)))); } var optionalAggregateRoot = ReconstructAggregateFrom <T>(domainEvents); return(optionalAggregateRoot.Unwrap( aggregateRoot => Task.FromResult(Ok(aggregateRoot)), () => throw new InvalidOperationException($"Unable to find any events for aggregate with ID '{aggregateId}'."))); }
public List <IDomainEvent> GetAll(IAggregateId aggregateId) { var file = File.ReadAllLines(GetFileName(aggregateId.Value)); var domainEvents = new List <IDomainEvent>(); foreach (var line in file) { var domainEvent = JsonConvert.DeserializeObject <IDomainEvent>(line, _jsonSerializerSettings); if (domainEvent == null) { continue; } domainEvents.Add(domainEvent); } return(domainEvents); }
//public void Add(EventsWrapper eventsWrapper) //{ // if (_dictionary.ContainsKey(eventsWrapper.AggregateId)) // { // var domainEvents = _dictionary[eventsWrapper.AggregateId]; // var sequenceId = domainEvents.Count; // if (sequenceId >= eventsWrapper.SequenceId) throw new SequenceAlreadyStoredException(); // domainEvents.AddRange(eventsWrapper.DomainEvents); // return; // } // foreach (var domainEvent in eventsWrapper.DomainEvents) // { // _dictionary.Add(eventsWrapper.AggregateId, new List<IDomainEvent> { domainEvent }); // } //} public void Add(IDomainEvent domainEvent, int sequenceId) { IAggregateId aggregateId = domainEvent.GetAggregateId(); if (_dictionary.ContainsKey(aggregateId)) { var domainEvents = _dictionary[aggregateId]; if (domainEvents.Count >= sequenceId) { throw new SequenceAlreadyStoredException(); } domainEvents.Add(domainEvent); return; } _dictionary.Add(aggregateId, new List <IDomainEvent> { domainEvent }); }
public List <IDomainEvent> GetAll(IAggregateId aggregateId) { var connection = Connection(); var readEvents = connection.ReadStreamEventsForwardAsync("newstream", 0, 10, true).Result; connection.Close(); List <IDomainEvent> domainEvents = new List <IDomainEvent>(); foreach (var evt in readEvents.Events) { var domainEvent = JsonConvert.DeserializeObject <IDomainEvent>(Encoding.UTF8.GetString(evt.Event.Data), _jsonSerializerSettings); if (domainEvent == null) { continue; } domainEvents.Add(domainEvent); } return(domainEvents); }
public static void Given <TState>(this ITestContext context, IAggregateId id, params EventRecord[] events) => context.Given(events.Select(e => EventEnvelope.Create(id.Id, e).AddTestMetaData <TState>(id)).ToArray());
public TestEvent(IAggregateId id) : this(id.Id) { }
public static string ToStreamName(this IAggregateId aggregateId, string eventStoreName) => $"{eventStoreName}|{aggregateId.TypeName}|{aggregateId.Id}";
private int GetSequenceId(IAggregateId aggregateId) { return(File.Exists(GetFileName(aggregateId.Value)) ? File.ReadAllLines(GetFileName(aggregateId.Value)).Length : 0); }
protected Aggregate(IAggregateId rootId) { this.RootId = rootId; }
public int CompareTo(IAggregateId other) => string.Compare(Id, other.Id, StringComparison.Ordinal);
public void Clear(IAggregateId aggregateId) { File.Delete(GetFileName(aggregateId.Value)); }
public static void Given <TState>(this ITestContext context, IAggregateId id, params IEvent[] events) => context.Given(events.Select(e => e.AddTestMetaData <TState>(id)).ToArray());
public static async Task SaveAsync(this IStateStore stateManager, IAggregateId aggregateId, object state, long version, IEvent[] events, Type type) { var mi = typeof(IStateStore).GetMethod("SaveAsync").MakeGenericMethod(type); await mi.InvokeAsync <bool>(stateManager, d => true, false, aggregateId, state, version, events); }
public void Clear(IAggregateId aggregateId) { throw new NotImplementedException(); }
public List <IDomainEvent> GetAll(IAggregateId aggregateId) { return(_dictionary.ContainsKey(aggregateId) ? _dictionary[aggregateId] : new List <IDomainEvent>()); }
public ItemAddedEvent(IAggregateId aggregateId) { this.AggregateId = Guid.Parse(aggregateId.ToString()); }
public WaitingOrder(IAggregateId id, int numberColis) { Id = id; NumberColis = numberColis; }
public static Task <T> GetAsync <T, TStream>(this IEventStore store, IAggregateId id) where T : class, new() => store.GetAsync <T>(typeof(TStream).Name.AsStreamName(id).StreamName);
public static async Task <(object Value, long Version)> GetAsync(this IStateStore stateManager, Type type, IAggregateId aggregateId) { var mi = typeof(IStateStore).GetMethod("GetAsync").MakeGenericMethod(type); return(await mi.InvokeAsync <(object, long)>(stateManager, d => (d.Item1, d.Item2), true, aggregateId)); }
protected MongoAggregate(IAggregateId rootId) : base(rootId) { }
public void Clear(IAggregateId aggregateId) { _dictionary.Remove(aggregateId); }
public async Task <WorkItemReadModel> Find(IAggregateId id) { return(await readDatabase.WorkItems.FirstOrDefaultAsync(x => x.Id == id.Value)); }