public static void ApplyEvent(dynamic @event, IAggregateState grainState) { dynamic state = grainState; @event.Apply(state); grainState.Version++; }
public BlockchainDBRepository( ILogger logger, IAggregateState <ItemMetadata> aggregateState, IOptions <NodeAppSettingsOptions> nodeAppSettingsOptions, IOptions <NodeP2PSettingsOptions> nodeP2POptions, IAzureBlobStore azureBlobStore ) { _logger = logger; _nodeAppSettingsOptions = nodeAppSettingsOptions.Value; _aggregateState = aggregateState; _aggregateState.PersistChain = true; _azureBlobStore = azureBlobStore; _azureBlobStore.Connect(); var nodeAddress = new NodeAddress("127.0.0.1", nodeP2POptions.Value.Port); var addressList = new List <NodeAddress>(); _p2PNode = new Node(nodeAddress, addressList); // wire up P2P behaviours _aggregateState.WireUpNode(_p2PNode); // setup indices _aggregateState.AddIndex(BlobRef_Idx, (item) => item.BlobRef); _aggregateState.AddIndex(Metadata_Name_Idx, (item) => item.Name); _aggregateState.AddIndex(Metadata_Value_Idx, (item) => item.Value); _aggregateState.InitialiseChainFromBlobs(); }
void IHaveState.AcceptState(IAggregateState state) { Ensure.That(state).IsNotNull(); Ensure.That(this.Data).Is(null); this.Data = ( TState )state; }
protected Aggregate(Guid id, long version, IAggregateState snapshot, IList <IEvent> history) { Id = id; Version = version + 1L; Hydrate(snapshot); foreach (var @event in history) { When(@event, false); } }
public void OnFlushEntity(FlushEntityEvent @event) { object entity = @event.Entity; IAggregateState oldState = entity as IAggregateState; if (oldState == null) { return; } IAggregateState newState = oldState.AggregateRoot.GetState(); @event.Session.Merge(newState); }
/// <summary> /// Apply events from the given <paramref name="history"/> that are handled by the <paramref name="state"/> /// calling the matching <see cref="IAggregateState{TEvent}.Apply(TEvent)"/> methods, using Reflection to /// determine which <see cref="IAggregateState{TEvent}"/> interfaces are implemented by <paramref name="state"/>. /// </summary> /// <remarks> /// Other options, less recommended, to restore the state from the event history: /// <list type="bullet"> /// <item><description> /// Loop through the events and make a <c>dynamic</c> dispatch <c>Apply((dynamic) @event)</c> /// but don't forget to have a fallback <c>Apply(object @event) {}</c> for unhandled events. /// </description></item> /// <item><description> /// Use pattern matching on the event type to call <see cref="IAggregateState{TEvent}.Apply(TEvent)"/> /// </description></item> /// </list> /// </remarks> public static void RestoreFrom(this IAggregateState state, IEnumerable <IDomainEvent> history) { var handledEvents = state.GetType() .GetInterfaces() .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IAggregateState <>)) .Select(x => new { EventType = x.GetGenericArguments()[0], ApplyMethod = x.GetMethod(nameof(IAggregateState <IDomainEvent> .Apply)), }) .ToList(); foreach (var @event in history) { var handledEvent = handledEvents.FirstOrDefault(x => x.EventType == @event.GetType()); handledEvent?.ApplyMethod?.Invoke(state, new object?[] { @event }); } }
public void Save(Guid aggregateId, IAggregateState state) { StateData storedState; if (store.TryGetValue(aggregateId, out storedState)) { storedState.Data = JsonConvert.SerializeObject(state, _jsonSettings); storedState.StateType = state.GetType().FullName; } else { storedState = new StateData() { Data = JsonConvert.SerializeObject(state, _jsonSettings), StateType = state.GetType().FullName }; store.Add(aggregateId, storedState); } }
protected virtual TAggregate CreateAggregateInstance <TAggregate>(IAggregateState state) { var aggregateType = typeof(TAggregate); var stateCtor = aggregateType .GetConstructors(bindingAttr: BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .SingleOrDefault(c => c.GetParameters().All(p => p.ParameterType == state.GetType())); if (stateCtor != null) { var aggregate = stateCtor.Invoke(new Object[] { state }); return(( TAggregate )aggregate); } else { var aggregateInstance = ( IHaveState )Activator.CreateInstance(typeof(TAggregate), true); aggregateInstance.AcceptState(state); return(( TAggregate )aggregateInstance); } }
private static bool IsAggregateRootDirty(ISession session, IAggregateState entity) { ISessionImplementor sessionImplementation = session.GetSessionImplementation(); IPersistenceContext persistenceContext = sessionImplementation.PersistenceContext; if (entity.IsProxy()) { entity = (IAggregateState)persistenceContext.Unproxy(entity); } EntityEntry entityEntry = persistenceContext.GetEntry(entity); IEntityPersister entityPersister = sessionImplementation.GetEntityPersister(null, entity); object[] oldState = entityEntry.LoadedState; object[] currentState = entityPersister.GetPropertyValues(entity, sessionImplementation.EntityMode); int[] findDirty = entityEntry.Persister.FindDirty(currentState, oldState, entity, sessionImplementation); bool hasDirtyCollection = currentState.OfType <IPersistentCollection>().Any(x => x.IsDirty); return((findDirty != null) || hasDirtyCollection); }
private static TEvent AppliedOn <TEvent>(this TEvent @event, IAggregateState <TEvent>?state) where TEvent : IDomainEvent => @event.With(_ => state?.Apply(@event));
/// <summary> /// Can be used to mutate the given <paramref name="state"/>, /// applying the given <paramref name="event"/> and then returning it. /// </summary> public static TEvent AppliedOn <TEvent>(this TEvent @event, IAggregateState state) where TEvent : IDomainEvent => @event.AppliedOn(state as IAggregateState <TEvent>);
public void Save(Guid aggregateId, IAggregateState state) { using (var db = _dbFactory()) { var storedState = db.AggregateStates.Find(aggregateId); if (storedState != null) { storedState.AggregateData = JsonConvert.SerializeObject(state, _jsonSettings); storedState.AggregateType = state.GetType().FullName; storedState.AggregateVersion += 1; } else { StateObject newState = new StateObject() { AggregateId = aggregateId, AggregateData = JsonConvert.SerializeObject(state, _jsonSettings), AggregateType = state.GetType().FullName, AggregateVersion = 1 }; db.AggregateStates.Add(newState); } db.SaveChanges(); } }
protected virtual void OnAggregateStateAdd(IAggregateState state) { this.OnAdd(state); }
public abstract void Hydrate(IAggregateState snapshot);
public Aggregate(IAggregateState state) { State = state; Changes = new List <object>(); PublishedEvents = new List <object>(); }