示例#1
0
 public static EventEntity ToEventEntity(this IAggregateEvent @event)
 {
     return(new EventEntity
     {
         PartitionKey = @event.Id,
         RowKey = ToEventFormat(@event.Version),
         EventJson = JsonConvert.SerializeObject(@event),
         EventName = @event.GetType().Name,
         EventType = @event.GetType().AssemblyQualifiedName
     });
 }
示例#2
0
        protected virtual bool Recover(IAggregateEvent <TAggregateSaga, TIdentity> aggregateEvent)
        {
            try
            {
                Logger.Debug($"Recovering with event of type [{aggregateEvent.GetType().PrettyPrint()}] ");
                ApplyEvent(aggregateEvent);
            }
            catch (Exception exception)
            {
                Logger.Error($"Recovering with event of type [{aggregateEvent.GetType().PrettyPrint()}] caused an exception {exception.GetType().PrettyPrint()}");
                return(false);
            }

            return(true);
        }
示例#3
0
        protected virtual void ApplyEvent(IAggregateEvent <TAggregate, TIdentity> aggregateEvent)
        {
            if (aggregateEvent == null)
            {
                throw new ArgumentNullException(nameof(aggregateEvent));
            }

            var eventType = aggregateEvent.GetType();

            if (_eventHandlers.ContainsKey(eventType))
            {
                _eventHandlers[eventType](aggregateEvent);
            }
            else if (_eventAppliers.Any(ea => ea.Apply((TAggregate)this, aggregateEvent)))
            {
                // Already done
            }
            else
            {
                if (applyMethods.Value.TryGetValue(eventType, out var applyMethod))
                {
                    applyMethod(this as TAggregate, aggregateEvent);
                }
                else
                {
                    throw new NotImplementedException(
                              $"Aggregate '{aggregateName.Value}' does have an 'Apply' method that takes aggregate event '{eventType.PrettyPrint()}' as argument");
                }
            }
        }
示例#4
0
        protected virtual void ApplyEvent(IAggregateEvent <TAggregate, TIdentity> aggregateEvent)
        {
            var eventType = aggregateEvent.GetType();

            if (_eventHandlers.ContainsKey(eventType))
            {
                _eventHandlers[eventType](aggregateEvent);
            }
            else if (_eventAppliers.Any(ea => ea.Apply((TAggregate)this, aggregateEvent)))
            {
                // Already done
            }
            else
            {
                Action <TAggregate, IAggregateEvent> applyMethod;
                if (!ApplyMethods.TryGetValue(eventType, out applyMethod))
                {
                    throw new NotImplementedException(
                              $"Aggregate '{Name}' does have an 'Apply' method that takes aggregate event '{eventType.PrettyPrint()}' as argument");
                }

                applyMethod(this as TAggregate, aggregateEvent);
            }

            Version++;
        }
示例#5
0
        private void ApplyEvent(IAggregateEvent aggregateEvent)
        {
            var applyMethod = GetApplyMethod(aggregateEvent.GetType());

            applyMethod(this as TAggregate, aggregateEvent);
            Version++;
        }
示例#6
0
 public static EventPublishedNotification ToEventPublishedNotification(this IAggregateEvent @event, Type subscriberType)
 {
     return(new EventPublishedNotification
     {
         EventJson = JsonConvert.SerializeObject(@event),
         EventType = @event.GetType().AssemblyQualifiedName,
         SubscriberType = subscriberType.AssemblyQualifiedName
     });
 }
示例#7
0
        public EventHistory(IAggregateEvent @event)
        {
            EventType = @event.GetType().Name;
            Version   = @event.Version;
            Event     = Singleton <IJsonConvert> .Instance.SerializeObject(@event);

            AggregateId  = @event.AggregateId;
            CreationTime = DateTime.UtcNow;
        }
示例#8
0
        private void InvokeEventHandlers(IAggregateEvent @event)
        {
            var eventType = @event.GetType();

            if (eventHandlers.ContainsKey(eventType))
            {
                eventHandlers[eventType].Invoke(@event);
            }
        }
        public EventData ToEventData(IAggregateEvent @event)
        {
            var dataJson = this._serializer.Serialize(@event);
            var data     = this._serializer.SerializeToBytes(dataJson);

            var metadataJson = this._serializer.Serialize(new EventMetadata(
                                                              assembly: @event.GetType().Assembly.Location,
                                                              eventType: @event.GetType().Name)
                                                          );
            var metadata = this._serializer.SerializeToBytes(metadataJson);

            return(new EventData(
                       eventId: Guid.NewGuid(),
                       type: @event.GetType().Name,
                       isJson: true,
                       data: data,
                       metadata: metadata
                       ));
        }
示例#10
0
        private A _applyEvent(A aggregate, IAggregateEvent @event)
        {
            //TODO: Probably better ways to do then. Don't like the casting and reflection

            // Get the event handler
            var t = typeof(IApplyEvent <,>).MakeGenericType(@event.GetType(), typeof(A));
            var handlersForEvent = _serviceLocator.GetInstances(t).ToList();

            if (handlersForEvent.Count == 0)
            {
                throw new NotImplementedException("No IApplyEvent found for type: " + t.FullName);
            }

            // Get the IApplyEvent that matches this IEvent.Version
            var correctVersionHandlers = handlersForEvent.Where(h =>
            {
                var versionProp = t.GetProperty("EventVersion");
                return((int)versionProp.GetValue(h) == @event.Version);
            }).ToList();

            // Thow if there where no implementations for this version of the event
            if (correctVersionHandlers.Count == 0)
            {
                throw new NotImplementedException($"No implementations of IApplyEvent found for type: '{t.FullName}' with version: {@event.Version}");
            }

            // Thow if there where multiple Apply implementaions for this verions of the event
            if (correctVersionHandlers.Count > 1)
            {
                throw new NotImplementedException($"Multiple implementations of IApplyEvent found for type: '{t.FullName}' and version: {@event.Version}");
            }

            // Apply the event and return the new aggregate state
            var handler = correctVersionHandlers.First(); // <-- Only 1 IApplyEvent for this version :-)

            // Kee the old aggregate version number
            var initialAggVersion = aggregate.AggregateVersion;

            // Apply
            var getMethod        = t.GetMethod("Apply");
            var updatedAggregate = (A)getMethod.Invoke(handler, new object[] { aggregate, @event });

            // make sure the developer didn't change the aggergate version.
            if (initialAggVersion != updatedAggregate.AggregateVersion)
            {
                throw new ApplicationException("Aggregate version changed. Handlers should not update the aggarate version.");
            }

            // Up the Aggregate  version. Only the command dispatcher should up the aggregate version
            aggregate.IncrementAggregateVersion();

            // Newly updated aggregate :-)
            return(updatedAggregate);
        }
示例#11
0
        public IEnumerable <KeyValuePair <string, string> > ProvideMetadata <TAggregate>(string id, IAggregateEvent aggregateEvent, IMetadata metadata) where TAggregate : IAggregateRoot
        {
            var aggregateEventType = aggregateEvent.GetType();
            var assembly           = aggregateEventType.Assembly;
            var name = assembly.GetName();

            yield return(new KeyValuePair <string, string>("event_type_assembly_version", name.Version.ToString()));

            yield return(new KeyValuePair <string, string>("event_type_assembly_name", name.Name));

            yield return(new KeyValuePair <string, string>("event_type_fullname", aggregateEventType.FullName));
        }
示例#12
0
        public static async Task ConsumeSubscribedEvent(this object subscriber, IAggregateEvent @event)
        {
            var type      = typeof(IHandleAggregateEventsOf <>);
            var eventType = @event.GetType();
            var fullType  = type.MakeGenericType(eventType);

            await(Task) fullType.InvokeMember(
                "HandleAsync",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                null,
                subscriber,
                new object[] { @event },
                CultureInfo.InvariantCulture);
        }
示例#13
0
        public static void ConsumeDispatchedEvent(this IAggregate aggregate, IAggregateEvent @event)
        {
            var type      = typeof(IDispatchAggregateEventsOf <>);
            var eventType = @event.GetType();
            var fullType  = type.MakeGenericType(eventType);

            fullType.InvokeMember(
                "Handle",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                null,
                aggregate,
                new object[] { @event },
                CultureInfo.InvariantCulture);
        }
        public void ApplyEvent(IAggregateEvent aggregateEvent)
        {
            var eventType = aggregateEvent.GetType();

            if (this._routes.ContainsKey(eventType))
            {
                this._routes[eventType](aggregateEvent);
            }
            else
            {
                throw new MssingEventRouteException(eventType, this.GetType());
            }

            this.Version++;
        }
示例#15
0
        public async Task Apply(IAggregateEvent <TIdentity> e)
        {
            await BeforeApply(e);

            var aggregateEventType = e.GetType();

            if (!ApplyMethods.TryGetValue(aggregateEventType, out var applier))
            {
                throw new MissingMethodException($"missing HandleAsync({aggregateEventType.Name})");
            }

            applier((TAggregateState)(object)this, e);

            await AfterApply(e);
        }
示例#16
0
        public bool Apply(
            TAggregate aggregate,
            IAggregateEvent <TAggregate, TIdentity> aggregateEvent)
        {
            var aggregateEventType = aggregateEvent.GetType();
            Action <TEventApplier, IAggregateEvent <TAggregate, TIdentity> > applier;

            if (!ApplyMethods.TryGetValue(aggregateEventType, out applier))
            {
                return(false);
            }

            applier((TEventApplier)(object)this, aggregateEvent);
            return(true);
        }
示例#17
0
        public IDomainEvent Create(IAggregateEvent aggregateEvent, IEventMetadata metadata)
        {
            var domainEventType = _aggregateEventToDomainEventTypeMap.GetOrAdd(aggregateEvent.GetType(), GetDomainEventType);
            var identityType    = _domainEventToIdentityTypeMap.GetOrAdd(domainEventType, GetIdentityType);
            var identity        = Activator.CreateInstance(identityType, metadata.AggregateId);

            var domainEvent = (IDomainEvent)Activator.CreateInstance(
                domainEventType,
                identity,
                aggregateEvent,
                metadata,
                metadata.Timestamp,
                metadata.AggregateSequenceNumber);

            return(domainEvent);
        }
示例#18
0
        public async Task UpdateAndSaveState(IAggregateEvent <TIdentity> @event)
        {
            var eventType   = @event.GetType();
            var applyMethod = GetApplierOfConcreteEvent(eventType);

            if (applyMethod == null)
            {
                var message = $"'{GetType().PrettyPrint()}' does not have an 'Apply' method that takes in a '{eventType.PrettyPrint()}'.";
                throw new NotImplementedException(message);
            }

            await PreApplyAction(@event);

            applyMethod.Invoke((TMessageApplier)(Object)this, @event);
            await PostApplyAction(@event);
        }
示例#19
0
        public SerializedEvent Serialize(IAggregateEvent aggregateEvent, IEnumerable <KeyValuePair <string, string> > metadatas)
        {
            var eventDefinition = _eventDefinitionService.GetEventDefinition(aggregateEvent.GetType());

            var metadata = new Metadata(metadatas.Concat(new[]
            {
                new KeyValuePair <string, string>(MetadataKeys.EventName, eventDefinition.Name),
                new KeyValuePair <string, string>(MetadataKeys.EventVersion, eventDefinition.Version.ToString(CultureInfo.InvariantCulture)),
            }));

            var dataJson = _jsonSerializer.Serialize(aggregateEvent);
            var metaJson = _jsonSerializer.Serialize(metadata);

            return(new SerializedEvent(
                       metaJson,
                       dataJson,
                       metadata.AggregateSequenceNumber));
        }
示例#20
0
        protected virtual void ApplyEvent(IAggregateEvent <TAggregate, TIdentity> aggregateEvent)
        {
            var eventType = aggregateEvent.GetType();

            if (_eventHandlers.ContainsKey(eventType))
            {
                _eventHandlers[eventType](aggregateEvent);
            }
            else if (_eventAppliers.Any(ea => ea.Apply((TAggregate)this, aggregateEvent)))
            {
            }
            else
            {
                var applyMethod = GetApplyMethod(eventType);
                applyMethod(this as TAggregate, aggregateEvent);
            }

            Version++;
        }
示例#21
0
        protected virtual void ApplyEvent(IAggregateEvent <TAggregate, TIdentity> aggregateEvent)
        {
            var eventType = aggregateEvent.GetType();

            if (_eventHandlers.ContainsKey(eventType))
            {
                _eventHandlers[eventType](aggregateEvent);
            }
            else if (_eventAppliers.Any(ea => ea.Apply((TAggregate)this, aggregateEvent)))
            {
                // Already done
            }

            var eventApplier = GetEventApplyMethods(aggregateEvent);

            eventApplier(aggregateEvent);

            Version++;
        }
        public bool EventIsOwnedByEntity(IAggregateEvent e, EntityBase entity)
        {
            if (entity.GetType() != entityType)
                return false;

            if (e.GetType() != eventType)
                return false;

            if (entityIdentityProperty == null)
            {
                object identity = aggregateIdentityProperty.GetValue(e);
                return entity.Identity.Equals(identity);
            }
            else
            {
                object identity = entityIdentityProperty.GetValue(e);
                return entity.Identity.Equals(identity);
            }
        }
 public bool CanHandleEvent(IAggregateEvent e)
 {
     return e.GetType() == eventType;
 }
 private static string GetErrorMessage(EntityBase entity, IAggregateEvent @event)
 {
     return String.Format("An error occured while invoking event handler {0} on {1}", @event.GetType().FullName, entity.GetType().FullName);
 }
示例#25
0
 public static string GetPrettyName(this IAggregateEvent aggregateEvent)
 => $"{aggregateEvent?.GetType().Name.Replace("Event", "")}";
 private static string GetErrorMessage(EntityBase entity, IAggregateEvent @event)
 {
     return String.Format("Unable to locate an event handler for {0} on {1}", @event.GetType().FullName, entity.GetType().FullName);
 }
示例#27
0
        protected void Apply(IAggregateEvent <TIdentity> @event)
        {
            var applier = GetApplierOfConcreteEvent(@event.GetType());

            applier((TMessageApplier)(Object)this, @event);
        }
示例#28
0
        internal protected void ApplyEvent(IAggregateEvent @event)
        {
            var m = this.GetType().GetMethod("Handle", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, new[] { @event.GetType() }, null);

            if (m == null)
            {
                throw new NotImplementedException(String.Format("Handle({0} @event) not implemented for type {1}.", @event.GetType().ToString(), this.GetType().ToString()));
            }
            m.Invoke(this, new[] { @event });
            _uncommittedEvents.Add(@event);
        }
示例#29
0
 private Task HandleEvent(IAggregateEvent @event)
 {
     this._logger.Information("{EventType} event was handled from EventBus", @event.GetType().Name);
     return(Task.CompletedTask);
 }
示例#30
0
 public IEnumerable <Type> GetSubscribersForEvent(IAggregateEvent @event)
 {
     this.GetSubscriberRegistry();
     return(this.registry.Subscriptions.Where(s => Type.GetType(s.EventType) == @event.GetType())
            .Select(s => Type.GetType(s.SubscriberType)));
 }
示例#31
0
 private void EnsureEventIsForTheCorrectAggregate(int nextExpectedId, IAggregateEvent @event)
 {
     if (nextExpectedId > 1 && @event.Id != this.aggregate.Id)
     {
         throw new UnexpectedEventException(
                   $"Aggregate {this.aggregate.GetType().Name} expected to load an event of Id {this.aggregate.Id} but received an event of type {@event.GetType().Name} with an id of {@event.Id}");
     }
 }