public void InjectDependencies(AggregateRoot aggregateRoot) { if (aggregateRoot != null) { aggregateRoot.EventPublisher = EventPublisher; } }
/// <summary> /// Gets the event handlers from aggregate root based on the given mapping. /// </summary> /// <param name="aggregateRoot">The aggregate root.</param> /// <see cref="ExpressionBasedDomainEventHandlerMappingStrategy"/> /// <returns>All the <see cref="IDomainEventHandler"/>'s created based on the given mapping.</returns> public IEnumerable<IDomainEventHandler> GetEventHandlersFromAggregateRoot(AggregateRoot aggregateRoot) { Contract.Requires<ArgumentNullException>(aggregateRoot != null, "The aggregateRoot cannot be null."); if(!(aggregateRoot is AggregateRootMappedWithExpressions)) { throw new ArgumentException("aggregateRoot need to be of type AggregateRootMappedWithExpressions to be used in a ExpressionBasedDomainEventHandlerMappingStrategy."); } var handlers = new List<IDomainEventHandler>(); foreach (ExpressionHandler mappinghandler in ((AggregateRootMappedWithExpressions)aggregateRoot).MappingHandlers) { if (mappinghandler.ActionMethodInfo.IsStatic) { var message = String.Format("The method {0}.{1} could not be mapped as an event handler, since it is static.", mappinghandler.ActionMethodInfo.DeclaringType.Name, mappinghandler.ActionMethodInfo.Name); throw new InvalidEventHandlerMappingException(message); } var handler = CreateHandlerForMethod(aggregateRoot, mappinghandler.ActionMethodInfo, mappinghandler.Exact); handlers.Add(handler); } return handlers; }
public bool TryLoadFromSnapshot(Type aggregateRootType, Snapshot snapshot, CommittedEventStream committedEventStream, out AggregateRoot aggregateRoot) { aggregateRoot = null; if (snapshot == null) return false; if (AggregateSupportsSnapshot(aggregateRootType, snapshot.Payload.GetType())) { Log.DebugFormat("Reconstructing aggregate root {0}[{1}] from snapshot", aggregateRootType.FullName, snapshot.EventSourceId.ToString("D")); aggregateRoot = _aggregateRootCreator.CreateAggregateRoot(aggregateRootType); aggregateRoot.InitializeFromSnapshot(snapshot); var memType = aggregateRoot.GetType().GetSnapshotInterfaceType(); var restoreMethod = memType.GetMethod("RestoreFromSnapshot"); restoreMethod.Invoke(aggregateRoot, new[] { snapshot.Payload }); Log.DebugFormat("Applying remaining historic event to reconstructed aggregate root {0}[{1}]", aggregateRootType.FullName, snapshot.EventSourceId.ToString("D")); aggregateRoot.InitializeFromHistory(committedEventStream); return true; } return false; }
/// <summary> /// Converts the given method into an <see cref="IDomainEventHandler"/> object. /// </summary> /// <param name="aggregateRoot">The aggregateroot from which we want to invoke the method.</param> /// <param name="method">The method to invoke</param> /// <param name="exact"><b>True</b> if we need to have an exact match, otherwise <b>False</b>.</param> /// <returns>An <see cref="IDomainEventHandler"/> that handles the execution of the given method.</returns> private static IDomainEventHandler CreateHandlerForMethod(AggregateRoot aggregateRoot, MethodInfo method, bool exact) { Type firstParameterType = method.GetParameters().First().ParameterType; Action<DomainEvent> handler = e => method.Invoke(aggregateRoot, new object[] { e }); return new TypeThresholdedActionBasedDomainEventHandler(handler, firstParameterType, exact); }
public void GetIdFrom_CalledWhenPropertyIsNull_ExpectInvalidOperationException() { var propertyName = Info.OfProperty<AggregateRoot>(x => x.ObjectProperty).Name; var getter = new NamedPropertyAggregateRootIdGetter<AggregateRoot, object>(propertyName); var aggregateRoot = new AggregateRoot { ObjectProperty = null }; getter.Invoking(x => x.GetIdFrom(aggregateRoot)).ShouldThrow<InvalidOperationException>(); }
public void DispatchPendingFor(AggregateRoot aggregate) { var pending = aggregate.DomainEvents; foreach (var domainEvent in pending) { Dispatch(domainEvent); } aggregate.ClearEvents(); }
protected Event( AggregateRoot sender, bool isLongRunning = false) { Requires.IsNotNull(sender, "sender"); Sender = sender; IsLongRunning = isLongRunning; }
public bool ShouldMakeSnapShot(AggregateRoot aggregate) { if (!IsSnapshotable(aggregate.GetType())) return false; var i = aggregate.Version; for (var j = 0; j < aggregate.GetUncommittedChanges().Count(); j++) if (++i % SnapshotInterval == 0 && i != 0) return true; return false; }
private AggregateRoot LoadAggregateRoot(string fullTypeName) { if(_aggregateRoot == null) { _aggregateRoot = (AggregateRoot)Activator.CreateInstance(Type.GetType(fullTypeName, true)); } return _aggregateRoot; }
public Task(AggregateRoot aggregateRoot, string name, string description) { _id = Guid.NewGuid(); _aggregateRoot = aggregateRoot; _name = name; _description = description; _status = TaskStatus.Active; _aggregateRoot.ApplyEvent(new TaskAddedEvent(_aggregateRoot.Id, _id, _name, _description)); }
private async Task SaveAndDispatchEvents(AggregateRoot root) { // Here should be the logic to persist this commit to some kind of store. // We use a stateless actor, so that means that this actor will be broken when it is pulled out of memory var commit = root.Commit(); // We push these events to the servicebus. var eventBusService = ServiceProxy.Create<IEventBusService>(new Uri("fabric:/CQRSMicroservices.ServiceFabric.Application/EventBusService")); await Task.WhenAll(commit.Events.ToList().Select(async e => await eventBusService.Dispatch(e.ToJson()))); }
public void CanReplay_CalledWhenAllPartsOfChainCannotReplay_ExpectFalseIsReturned( AggregateRoot aggregateRootOrNull, DomainEvent domainEventOrNull, ConstructWith construct) { var aggregateRoot = aggregateRootOrNull.ToObject(); var domainEvent = domainEventOrNull.ToObject(); var innerReplays = AtLeastOneReplayStubbedForCannotReplay().ToArray(); var chain = construct.WithChain(innerReplays); chain.CanReplay(aggregateRoot, domainEvent).Should().BeFalse(); }
public string SerializeObject(AggregateRoot rootInstance) { try { return JsonConvert.SerializeObject(rootInstance, SerializerSettings); } catch (Exception exception) { throw new JsonSerializationException(string.Format("Could not serialize aggregate root {0} with ID {1}", rootInstance.GetType(), rootInstance), exception); } }
public bool TryTakeSnapshot(AggregateRoot aggregateRoot, out Snapshot snapshot) { snapshot = null; MethodInfo createMethod = aggregateRoot.GetType().GetSnapshotCreateMethod(); if (createMethod != null) { object payload = createMethod.Invoke(aggregateRoot, new object[0]); snapshot = new Snapshot(aggregateRoot.EventSourceId, aggregateRoot.Version, payload); return true; } return false; }
public bool TryTakeSnapshot(AggregateRoot aggregateRoot, out Snapshot snapshot) { snapshot = null; var memType = aggregateRoot.GetType().GetSnapshotInterfaceType(); if (memType != null) { var createMethod = memType.GetMethod("CreateSnapshot"); var payload = createMethod.Invoke(aggregateRoot, new object[0]); snapshot = new Snapshot(aggregateRoot.EventSourceId, aggregateRoot.Version, payload); return true; } return false; }
public static CacheEntry Create(AggregateRoot aggregateRootInfo) { var rootInstance = aggregateRootInfo; var data = Sturdylizer.SerializeObject(rootInstance); return new CacheEntry { SequenceNumber = aggregateRootInfo.CurrentSequenceNumber, GlobalSequenceNumber = aggregateRootInfo.GlobalSequenceNumberCutoff, AggregateRootId = aggregateRootInfo.Id, AggregateRootType = rootInstance.GetType(), Hits = 0, TimeOfLastHit = DateTime.UtcNow, Data = data }; }
public void CanReplay_CalledWhenAnyPartOfChainCanReplay_ExpectTrueIsReturned( AggregateRoot aggregateRootOrNull, DomainEvent domainEventOrNull, ConstructWith construct) { var aggregateRoot = aggregateRootOrNull.ToObject(); var domainEvent = domainEventOrNull.ToObject(); var innerReplays = AtLeastOneReplayStubbedForCanReplay(aggregateRoot, domainEvent) .Concat(AnyNumberOfReplaysStubbedForCannotReplay()) .Shuffle() .ToArray(); var chain = construct.WithChain(innerReplays); chain.CanReplay(aggregateRoot, domainEvent).Should().BeTrue(); }
public void Store(AggregateRoot aggregateRoot) { lock (BackingStore) { var version = aggregateRoot.BuiltFromVersion; var lastEvent = RetrieveEventsFor(aggregateRoot.Id).Last(); if ((lastEvent != null) && (version != lastEvent.AggregateRootVersion)) { throw new EventStoreConcurrencyException(aggregateRoot.GetType(), aggregateRoot.Id, version, lastEvent.AggregateRootVersion); } foreach (var @event in aggregateRoot.ExtractEvents()) { @event.AggregateRootVersion = version++; BackingStore.Add(@event); } } }
public bool TryLoadFromSnapshot(Type aggregateRootType, Snapshot snapshot, CommittedEventStream committedEventStream, out AggregateRoot aggregateRoot) { aggregateRoot = null; if (snapshot == null) return false; if (AggregateSupportsSnapshot(aggregateRootType, snapshot.Payload.GetType())) { aggregateRoot = _aggregateRootCreator.CreateAggregateRoot(aggregateRootType); aggregateRoot.InitializeFromSnapshot(snapshot); MethodInfo restoreMethod = aggregateRoot.GetType().GetSnapshotRestoreMethod(); restoreMethod.Invoke(aggregateRoot, new[] {snapshot.Payload}); aggregateRoot.InitializeFromHistory(committedEventStream); return true; } return false; }
public IEnumerable<IDomainEventHandler> GetEventHandlersFromAggregateRoot(AggregateRoot aggregateRoot) { Contract.Requires<ArgumentNullException>(aggregateRoot != null, "The aggregateRoot cannot be null."); Contract.Ensures(Contract.Result<IEnumerable<IDomainEventHandler>>() != null, "The result should never be null."); var targetType = aggregateRoot.GetType(); var handlers = new List<IDomainEventHandler>(); Logger.DebugFormat("Trying to get all event handlers based by convention for {0}.", targetType); var methodsToMatch = targetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var matchedMethods = from method in methodsToMatch let parameters = method.GetParameters() let noEventHandlerAttributes = method.GetCustomAttributes(typeof(NoEventHandlerAttribute), true) where // Get only methods where the name matches. Regex.IsMatch(method.Name, _regexPattern, RegexOptions.CultureInvariant) && // Get only methods that have 1 parameter. parameters.Length == 1 && // Get only methods where the first parameter is an event. typeof(DomainEvent).IsAssignableFrom(parameters[0].ParameterType) && // Get only methods that are not marked with the no event handler attribute. noEventHandlerAttributes.Length == 0 select new { MethodInfo = method, FirstParameter = method.GetParameters()[0] }; foreach (var method in matchedMethods) { var methodCopy = method.MethodInfo; Type firstParameterType = methodCopy.GetParameters().First().ParameterType; Action<DomainEvent> invokeAction = (e) => methodCopy.Invoke(aggregateRoot, new object[] { e }); Logger.DebugFormat("Created event handler for method {0} based on convention.", methodCopy.Name); var handler = new TypeThresholdedActionBasedDomainEventHandler(invokeAction, firstParameterType, true); handlers.Add(handler); } return handlers; }
/// <summary> /// Gets the event handlers from aggregate root based on attributes. /// </summary> /// <param name="aggregateRoot">The aggregate root.</param> /// <see cref="AttributeBasedDomainEventHandlerMappingStrategy"/> /// <returns>All the <see cref="IDomainEventHandler"/>'s created based on attribute mapping.</returns> public IEnumerable<IDomainEventHandler> GetEventHandlersFromAggregateRoot(AggregateRoot aggregateRoot) { Contract.Requires<ArgumentNullException>(aggregateRoot != null, "The aggregateRoot cannot be null."); var targetType = aggregateRoot.GetType(); var handlers = new List<IDomainEventHandler>(); foreach (var method in targetType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { EventHandlerAttribute attribute; if (IsMarkedAsEventHandler(method, out attribute)) { if (method.IsStatic) // Handlers are never static. Since they need to update the internal state of an eventsource. { var message = String.Format("The method {0}.{1} could not be mapped as an event handler, since it is static.", method.DeclaringType.Name, method.Name); throw new InvalidEventHandlerMappingException(message); } if (NumberOfParameters(method) != 1) // The method should only have one parameter. { var message = String.Format("The method {0}.{1} could not be mapped as an event handler, since it has {2} parameters where 1 is required.", method.DeclaringType.Name, method.Name, NumberOfParameters(method)); throw new InvalidEventHandlerMappingException(message); } if (!typeof(DomainEvent).IsAssignableFrom(FirstParameterType(method))) // The parameter should be an IEvent. { var message = String.Format("The method {0}.{1} could not be mapped as an event handler, since it the first parameter is not an event type.", method.DeclaringType.Name, method.Name); throw new InvalidEventHandlerMappingException(message); } var handler = CreateHandlerForMethod(aggregateRoot, method, attribute); handlers.Add(handler); } } return handlers; }
public static object GetMemento(this AggregateRoot aggregateRoot) { return(aggregateRoot.GetMemento()); }
public static IEnumerable <object> GetUncommittedEvents(this AggregateRoot aggregateRoot) { return(aggregateRoot.GetUncommittedEvents()); }
protected async override Task <AccountRoot> Apply(RemovePaymentCommand command, CancellationToken cancellationToken) { AggregateRoot.DeleteBooking(Domain.BookingId.FromGuid(command.BookingId)); return(await Task.FromResult(AggregateRoot)); }
public Order(AggregateRoot parent, Guid entityId) : base(parent, entityId) { }
public void AddToCache(AggregateRoot aggregateRoot, long globalSequenceNumberCutoff) { _realUnitOfWork.AddToCache(aggregateRoot, globalSequenceNumberCutoff); }
public HandlerNotRegisteredException(AggregateRoot aggregateRoot, Event @event) : this(aggregateRoot.GetType(), @event.GetType()) { }
public void Save(AggregateRoot aggregate, int expectedVersion) { _storage.SaveEvents(aggregate.Id, aggregate.GetUncommittedChanges(), expectedVersion); }
/// <summary> /// Creates the snapshot instance /// </summary> public Snapshot(long validFromGlobalSequenceNumber, AggregateRoot instance) { ValidFromGlobalSequenceNumber = validFromGlobalSequenceNumber; Instance = instance; }
public Story(AggregateRoot parent, Sprint sprint, Guid id, string description) : base(parent, id) { _sprint = sprint; _description = description; }
public AggregateTest() { _aggregate = (AggregateRoot)Activator.CreateInstance(typeof(TAggregate)) !; _repository = new FakeAggregateStore(_aggregate); }
private static void DefineContribution(SchemaSpecification schema, AggregateRoot mathematician, AggregateRoot field) { var table = schema.CreateTable("Contribution"); var contributionId = table.CreateIdentityColumn("ContributionId"); var pk = table.CreatePrimaryKey(contributionId); var mathematicianId = table.CreateIntColumn("MathematicianId"); var description = table.CreateStringColumn("Description", 500); var fieldId = table.CreateIntColumn("FieldId"); var indexMathematicianId = table.CreateIndex(mathematicianId); var fkMathematician = indexMathematicianId.CreateForeignKey(mathematician.PrimaryKey); var indexFieldId = table.CreateIndex(fieldId); var fkField = indexFieldId.CreateForeignKey(field.PrimaryKey); }
public ProductQuantityAdded(AggregateRoot aggregate, int addedQuantity) { AggregateId = aggregate.AggregateId; AddedQuantity = addedQuantity; EventType = typeof(ProductQuantityAdded).Name; }
void OnCommitted <TAggregateRoot>(string aggregateRootId, IUnitOfWork unitOfWork, AggregateRoot aggregateRootInstance, long checkedOutSequenceNumber) { unitOfWork.Committed += eventBatch => { var aggregateRootHasChanges = new AggregateRootInfo(aggregateRootInstance).SequenceNumber != checkedOutSequenceNumber; if (!aggregateRootHasChanges) { return; } var lastGlobalSequenceNumber = eventBatch.Max(e => e.GetGlobalSequenceNumber()); _snapshotStore.SaveSnapshot <TAggregateRoot>(aggregateRootId, aggregateRootInstance, lastGlobalSequenceNumber); }; }
public IActionResult Post(SaveDataModel model) { if (model.EntityId.Equals(Guid.Empty)) { return(NotFound()); } var entityMetaData = _entityFinder.FindById(model.EntityId); if (entityMetaData == null) { return(NotFound()); } AggregateRoot aggregateRoot = new AggregateRoot(); var attributeMetaDatas = _attributeFinder.FindByEntityId(model.EntityId); bool isNew = !(model.RecordId.HasValue && !model.RecordId.Value.Equals(Guid.Empty)); var thisId = Guid.Empty; try { Core.Data.Entity entity = new Core.Data.Entity(entityMetaData.Name); dynamic headData = JObject.Parse(model.Data); foreach (JProperty p in headData) { var attr = attributeMetaDatas.Find(n => n.Name.IsCaseInsensitiveEqual(p.Name)); if (attr != null && p.Value != null) { entity.SetAttributeValue(p.Name.ToString().ToLower(), entity.WrapAttributeValue(_entityFinder, attr, p.Value.ToString())); } } if (isNew) { if (model.RelationShipName.IsNotEmpty() && model.ReferencedRecordId.HasValue)//如果存在关联关系 { var relationShipMetas = _relationShipFinder.FindByName(model.RelationShipName); if (null != relationShipMetas && relationShipMetas.ReferencingEntityId == model.EntityId && entity.GetStringValue(relationShipMetas.ReferencingAttributeName).IsEmpty()) { //设置当前记录关联字段的值 entity.SetAttributeValue(relationShipMetas.ReferencingAttributeName, new EntityReference(relationShipMetas.ReferencedEntityName, model.ReferencedRecordId.Value)); } } if (!model.StageId.Equals(Guid.Empty))//业务流程的阶段 { entity.SetAttributeValue("StageId", model.StageId); } //thisId = _dataCreater.Create(entity); if (!model.StageId.Equals(Guid.Empty))//业务流程的阶段 { _businessProcessFlowInstanceUpdater.UpdateForward(model.BusinessFlowId, model.BusinessFlowInstanceId, model.StageId, thisId); } } else { thisId = model.RecordId.Value; entity.SetIdValue(model.RecordId.Value); //_dataUpdater.Update(entity); } aggregateRoot.MainEntity = entity; aggregateRoot.ChildEntities = new List <RefEntity>(); //单据体 if (model.Child.IsNotEmpty()) { var childs = JArray.Parse(model.Child.UrlDecode()); if (childs.Count > 0) { List <Core.Data.Entity> childEntities = new List <Core.Data.Entity>(); List <string> entityNames = new List <string>(); foreach (var c in childs) { dynamic root = JObject.Parse(c.ToString()); string name = root.name, relationshipname = root.relationshipname, refname = string.Empty; OperationTypeEnum?entitystatus = root.entitystatus; if (!entityNames.Exists(n => n.IsCaseInsensitiveEqual(name))) { entityNames.Add(name); } var data = root.data; var childAttributes = _attributeFinder.FindByEntityName(name); if (relationshipname.IsNotEmpty()) { var relationShipMetas = _relationShipFinder.FindByName(relationshipname); if (null != relationShipMetas && relationShipMetas.ReferencedEntityId == model.EntityId) { refname = relationShipMetas.ReferencingAttributeName; } } Core.Data.Entity detail = new Core.Data.Entity(name); RefEntity refEntity = new RefEntity() { Name = name, Relationshipname = relationshipname, Entityid = model.EntityId, Entitystatus = entitystatus }; foreach (JProperty p in data) { var attr = childAttributes.Find(n => n.Name.IsCaseInsensitiveEqual(p.Name)); if (attr != null && p.Value != null) { detail.SetAttributeValue(p.Name.ToString().ToLower(), detail.WrapAttributeValue(_entityFinder, attr, p.Value.ToString())); } refEntity.Entity = detail; } //关联主记录ID if (refname.IsNotEmpty()) { detail.SetAttributeValue(refname, new EntityReference(entityMetaData.Name, thisId)); } aggregateRoot.ChildEntities.Add(refEntity); } } } model.FormId = null; if (isNew) { thisId = _aggCreater.Create(aggregateRoot, model.FormId); } else { _aggUpdater.Update(aggregateRoot, model.FormId); } } catch (Exception ex) { return(JError(ex.InnerException != null ? ex.InnerException.Message : ex.Message)); } if (isNew) { return(CreateSuccess(new { id = thisId })); } return(UpdateSuccess(new { id = thisId })); }
public void GetIdFrom_CalledWhenPropertyIsPublic_ExpectValueOfPropertyIsReturned() { var propertyName = Info.OfProperty<AggregateRoot>(x => x.ObjectProperty).Name; var getter = new NamedPropertyAggregateRootIdGetter<AggregateRoot, object>(propertyName); var aggregateRoot = new AggregateRoot { ObjectProperty = new object() }; getter.GetIdFrom(aggregateRoot).Should().BeSameAs(aggregateRoot.ObjectProperty); }
/// <summary>Always return false. /// </summary> /// <param name="aggregateRoot"></param> /// <returns></returns> public bool ShouldCreateSnapshot(AggregateRoot aggregateRoot) { return false; }
public Task Set(Guid id, AggregateRoot aggregate) { _cache[id] = aggregate; return(Task.CompletedTask); }
public FrozenAggregateRootService(AggregateRoot aggregateRootInfo, RealUnitOfWork realUnitOfWork) { _aggregateRootInfo = aggregateRootInfo; _realUnitOfWork = realUnitOfWork; }
public Snapshot TryTakeSnapshot(AggregateRoot aggregateRoot) { Snapshot snapshot; _aggregateSnapshotter.TryTakeSnapshot(aggregateRoot, out snapshot); return snapshot; }
public EventStreamAndAggregateRoot(EventStream eventStream, AggregateRoot aggregateRoot) { EventStream = eventStream; AggregateRoot = aggregateRoot; }
protected override void When() { AggregateRoot.AddEntity(newChildName); }
private async Task ProcessDomainEvents(AggregateRoot root) { await _eventDispatcher.DispatchAsync(root.DomainEvents); root.ClearDomainEvents(); }
/// <summary> /// 跟踪某个聚合根 /// </summary> public void TrackingAggregateRoot(AggregateRoot aggregateRoot) { _unitOfWork.TrackingAggregateRoot(aggregateRoot); }
public AggregateRootInfo(AggregateRoot instance) { Instance = instance; }
public void Save(AggregateRoot aggregate, int expectedVersion) { //while testing, don't persist events to the event store, we will just keep track of them here _uncommittedEvents.AddRange(aggregate.GetUncommittedEvents); aggregate.ClearUncommittedEvents(); }
public UserCreated(AggregateRoot root, string name, int age) : base(root) { Name = name; Age = age; }
public static string GetViewIdFromAggregateRoot(AggregateRoot aggregateRoot) { return GetViewIdFromAggregateRootId(aggregateRoot.Id); }
public EventStreamAndAggregateRoot(EventStream eventStream, AggregateRoot aggregateRoot) { this.EventStream = eventStream; this.AggregateRoot = aggregateRoot; }
public static int GetRevision(this AggregateRoot aggregateRoot) { return(aggregateRoot.Revision); }
public static async Task PublishDomainEventsOf(this IPipelineContext context, AggregateRoot aggregate) { await Task.WhenAll(aggregate.NewEvents.Select(context.Publish)).ConfigureAwait(false); aggregate.ForgetNewEvents(); }
public AggregateToSave(AggregateRoot aggregate, List <NewStreamMessage> messages) { Aggregate = aggregate; Messages = messages; }