示例#1
0
        public StoredEvent Append(IDomainEvent domainEvent)
        {
            var storedEvent = new StoredEvent(
                domainEvent.GetType().FullName + ", " + domainEvent.GetType().Assembly.GetName().Name,
                domainEvent.OccurredOn,
                domainEvent.ToString(),
                domainEvent.EventId,
                StoredEvent.ToStorePayload(domainEvent),
                domainEvent.UserId,
                domainEvent.ProcessId,
                domainEvent.UserId);

            try
            {
                _appendOnlyStore.Append(storedEvent);

                return(storedEvent);
            }
            catch (Exception e)
            {
                CustomErrorSignal.Handle(e);
            }

            return(null);
        }
示例#2
0
        /// <summary>
        /// Determines if the event is pre-transaction
        /// </summary>
        /// <param name="event">The domain event</param>
        /// <returns>True, if the event is pre-transaction; otherwise false</returns>
        public static bool IsPostTransaction
        (
            this IDomainEvent @event
        )
        {
            Validate.IsNotNull(@event);

            var hasPreAttribute = Attribute.IsDefined
                                  (
                @event.GetType(),
                typeof(PreTransactionEventAttribute)
                                  );

            if (false == hasPreAttribute)
            {
                return(true);
            }
            else
            {
                var hasPostAttribute = Attribute.IsDefined
                                       (
                    @event.GetType(),
                    typeof(PostTransactionEventAttribute)
                                       );

                if (hasPostAttribute)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Register asynchronously an event to be processed by the bus.
        /// </summary>
        /// <param name="event">Event to register.</param>
        /// <param name="context">Context associated to the event..</param>
        public Task <Result> PublishEventAsync(IDomainEvent @event, IEventContext context = null)
        {
            try
            {
                if (@event != null)
                {
                    var queue = Helpers.GetMessageQueue(_configuration.QueueName);

                    var      evtCfg     = _configuration.EventsLifetime.FirstOrDefault(t => new TypeEqualityComparer().Equals(t.Type, @event.GetType()));
                    TimeSpan?expiration = null;
                    if (evtCfg.Expiration.TotalMilliseconds > 0)
                    {
                        expiration = evtCfg.Expiration;
                    }

                    var serializedEvent = _serializer.SerializeEvent(@event);
                    var enveloppe       = expiration.HasValue
                        ? new Enveloppe(serializedEvent, @event.GetType(), _emiter, true, expiration.Value)
                        : new Enveloppe(serializedEvent, @event.GetType(), _emiter);

                    var message = new Message(enveloppe)
                    {
                        TimeToBeReceived = enveloppe.Expiration,
                        Formatter        = new JsonMessageFormatter()
                    };
                    queue.Send(message);
                }
                return(Task.FromResult(Result.Ok()));
            }
            catch
            {
                return(Task.FromResult(Result.Fail()));
            }
        }
示例#4
0
 public IEnumerable<Action<IDomainEvent>> GetEventHandlerActions(IDomainEvent domainEvent)
 {
     var handlers = _container.ResolveAll(typeof(IHandler<>).MakeGenericType(domainEvent.GetType()));
     foreach (var handler in handlers)
     {
         var method = handler.GetType().GetMethod("Handle", new Type[] { domainEvent.GetType() });
         yield return @event => method.Invoke(handler, new object[] { @event });
     }
 }
示例#5
0
        private static void onRaiseEvent(IDomainEvent e)
        {
            Console.WriteLine(e.GetType().ToString());
            var handlerInterfaceType = typeof(IDomainEventHandler <>).MakeGenericType(e.GetType());
            var handler = serviceProvider.GetService(handlerInterfaceType);
            var method  = handler?.GetType().GetMethod("Handle", new Type[] { e.GetType() });

            method?.Invoke(handler, new[] { e });
        }
		public void Handle(IAggregateRoot root, IDomainEvent ev)
		{
			MethodInvoker invoker;
			if (!_handlers.TryGetValue(ev.GetType(), out invoker))
			{
				throw new InvalidOperationException(string.Format("Apply method for event [{0}] wasn't resolved in [{1}]", ev.GetType().Name, root.GetType().Name));
			}

			invoker.Invoke(root, new object[] {ev});
		}
示例#7
0
        protected void AddActivityLog(AdminActivityLogCategory category, IDomainEvent @event, string performedBy = null)
        {
            var defaultPropertyNames = typeof(IDomainEvent).GetProperties().Select(pi => pi.Name);
            var customProperties     = @event.GetType().GetProperties().Where(pi => !defaultPropertyNames.Contains(pi.Name));
            var activityName         = @event.GetType().Name.SeparateWords();
            var remark = GetRemark(@event, customProperties);

            var actionMadeBy = performedBy ?? @event.EventCreatedBy;

            AddActivityLog(category, activityName, @event, actionMadeBy, remark);
        }
示例#8
0
        private void InvokeApply(IDomainEvent domainEvent)
        {
            var method = GetType().GetMethod("Apply", new Type[] { domainEvent.GetType() });

            if (method == null)
            {
                throw new DomainException("Cannot find method: Apply(" + domainEvent.GetType().Name + ")");
            }

            method.Invoke(this, new object[] { domainEvent });
        }
示例#9
0
        private void RaiseEvent(IDomainEvent @event)
        {
            if (!_handlers.ContainsKey(@event.GetType()))
            {
                throw new InvalidOperationException($"Missing handler for {@event.GetType()}");
            }

            _handlers[@event.GetType()](@event);
            _uncommitedEvents.Add(@event);
            Version++;
        }
示例#10
0
 public static EventStoreItem FromDomainEvent(IDomainEvent @event)
 {
     return(new EventStoreItem()
     {
         Id = Guid.NewGuid().ToString(),
         DateTime = @event.DateTime,
         AggregateId = @event.AggregateId.ToString(),
         Version = @event.Version,
         EventType = $"{@event.GetType().FullName}, {@event.GetType().Assembly.GetName().Name}",
         EventData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event))
     });
 }
示例#11
0
        private EventMetadata GetHeaders(IDomainEvent @event)
        {
            var headers = new EventMetadata
            {
                EventId        = @event.EventId,
                EventName      = @event.GetType().GetEventName(),
                EventVersion   = @event.GetType().GetEventVersion(),
                EventNamespace = @event.GetType().GetEventNamespace()
            };

            return(headers);
        }
        /// <summary>
        /// Dispatch a new event to all listeners.
        /// </summary>
        /// <param name="e">Domain event</param>
        /// <remarks>Exceptions are not handled and will there break the processing. It's up to the caller to process any exceptions.</remarks>
        public void Dispatch(IDomainEvent e)
        {
            if (e == null) throw new ArgumentNullException("e");

            var type = typeof (IAutoSubscriberOf<>).MakeGenericType(e.GetType());
            var invokeMethod = type.GetMethod("Handle", new[] {e.GetType()});
            var parameters = new object[] {e};
            foreach (var handler in ServiceResolver.Current.ResolveAll(type))
            {
                invokeMethod.Invoke(handler, parameters);
            }
        }
示例#13
0
        public static bool TryGetEventNameAttribute(this IDomainEvent @event, out string eventName)
        {
            EventNameAttribute attribute;

#if REFLECTIONBRIDGE && (!(NET40 || NET35 || NET20))
            attribute = @event.GetType().GetCustomAttribute <EventNameAttribute>();
#else
            attribute = @event.GetType().GetTypeInfo().GetCustomAttribute <EventNameAttribute>();
#endif
            eventName = attribute?.EventName;

            return(!string.IsNullOrWhiteSpace(eventName));
        }
        public static string GetDisplayName(this IDomainEvent domainEvent)
        {
            var displayName = domainEvent.GetType()
                              .GetCustomAttributes(typeof(DisplayAttribute), false)
                              .FirstOrDefault() as DisplayAttribute;

            if (displayName != null)
            {
                return(displayName.Name);
            }

            return(domainEvent.GetType().Name);
        }
        private async Task DispatchToSubscribersAsync(
            IDomainEvent domainEvent,
            Type subscriberType,
            bool swallowException,
            CancellationToken cancellationToken)
        {
            var subscriberInformation = await GetSubscriberInformationAsync(
                domainEvent.GetType(),
                subscriberType,
                cancellationToken)
                                        .ConfigureAwait(false);

            var subscribers = _resolver.ResolveAll(subscriberInformation.SubscriberType)
                              .Cast <ISubscribe>()
                              .OrderBy(s => s.GetType().Name)
                              .ToList();

            if (!subscribers.Any())
            {
                _log.Debug(() => $"Didn't find any subscribers to '{domainEvent.EventType.PrettyPrint()}'");
                return;
            }

            var exceptions = new List <Exception>();

            foreach (var subscriber in subscribers)
            {
                try
                {
                    await DispatchToSubscriberAsync(
                        domainEvent,
                        subscriber,
                        subscriberInformation,
                        swallowException,
                        cancellationToken)
                    .ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    exceptions.Add(e);
                }
            }

            if (exceptions.Any())
            {
                throw new AggregateException(
                          $"Dispatch of domain event {domainEvent.GetType().PrettyPrint()} to subscribers failed",
                          exceptions);
            }
        }
示例#16
0
        public static string Serialize(IDomainEvent ev)
        {
            var serializer = new XmlSerializer(ev.GetType());

            var serializedEvent = new StringBuilder();

            using (var writer = new StringWriter(serializedEvent))
            {
                serializer.Serialize(writer, ev);
            }

            return ev.GetType().AssemblyQualifiedName + "|" +
                   serializedEvent.ToString().Replace(Environment.NewLine, "");
        }
示例#17
0
        public void Send(IDomainEvent domainEvent)
        {
            //
            // TODO: Catch failures (NotFound, Duplicated Handlers, etc)
            //

            dynamic handlersList = Convert.ChangeType(handlers[domainEvent.GetType()], typeof(List <object>));
            dynamic message      = Convert.ChangeType(domainEvent, domainEvent.GetType());

            foreach (var handler in handlersList)
            {
                handler.Handle(message);
            }
        }
示例#18
0
        protected virtual bool Recover(IDomainEvent <TAggregateSaga, TIdentity, IAggregateEvent <TAggregateSaga, TIdentity> > domainEvent)
        {
            try
            {
                Logger.Debug($"Recovering with event of type [{domainEvent.GetType().PrettyPrint()}] ");
                ApplyEvent(domainEvent.AggregateEvent);
            }
            catch (Exception exception)
            {
                Logger.Error($"Recovering with event of type [{domainEvent.GetType().PrettyPrint()}] caused an exception {exception.GetType().PrettyPrint()}");
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Applies the specified <see cref="IDomainEvent"/> to the current state by invoking the appropriate When method
        /// that takes a particular event.
        /// </summary>
        public void Process(IDomainEvent @event)
        {
            if ([email protected]().HasAttribute<ObsoleteAttribute>())
            {
                MethodInfo info = EventMappingCache.GetHandlerFor(GetType(), @event.GetType());

                try
                {
                    info.Invoke(this, new[] { @event });
                }
                catch (TargetInvocationException ex)
                {
                    throw ex.Unwrap();
                }
            }
        }
示例#20
0
 private void InvokeEventHandler(IDomainEvent e) {
     var eventHandlerName = "On" + e.GetType().Name;
     var methodInfo = GetType().GetMethod(eventHandlerName,
         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
     methodInfo.Invoke(this, new[] {e});
     version++;
 }
示例#21
0
        private async Task PrepareForEventInsertionAsync(IDomainEvent @event)
        {
            var evtType = @event.GetType();
            ISnapshotBehavior behavior = _snapshotBehaviorProvider?.GetBehaviorForEventType(evtType);

            CheckIdAndSetNewIfNeeded(@event);
            ulong?sequence = null;

            if (@event.AggregateId != null)
            {
                await SetSequenceAsync(@event, sequence).ConfigureAwait(false);

                if (_archiveBehavior != SnapshotEventsArchiveBehavior.Disabled &&
                    behavior?.IsSnapshotNeeded(@event) == true)
                {
                    var aggregateState = await GetRehydratedStateAsync(@event.AggregateId, @event.AggregateType).ConfigureAwait(false);

                    var result = behavior.GenerateSnapshot(aggregateState);
                    if (result?.Any() == true)
                    {
                        if (aggregateState != null)
                        {
                            await InsertSnapshotAsync(
                                new Snapshot(@event.AggregateId, @event.AggregateType, aggregateState, behavior.GetType(), DateTime.Now)
                                ).ConfigureAwait(false);
                        }
                        await StoreArchiveEventsAsync(result).ConfigureAwait(false);
                    }
                }
            }
        }
示例#22
0
        /// <summary>
        /// Compiles the domain event properties onto a dictionary
        /// </summary>
        /// <param name="event">The domain event</param>
        /// <returns>The event details as a dictionary</returns>
        private Dictionary <string, string> CompileEventProperties
        (
            IDomainEvent @event
        )
        {
            Validate.IsNotNull(@event);

            var properties = new Dictionary <string, string>()
            {
                { "EventTypeName", @event.GetType().Name },
                { "EventDescription", @event.ToString() }
            };

            var eventLog = DomainEventLog.CreateLog
                           (
                @event
                           );

            foreach (var detail in eventLog.Details)
            {
                AppendDetail
                (
                    ref properties,
                    detail
                );
            }

            return(properties);
        }
        protected virtual bool Dispatch(IDomainEvent domainEvent)
        {
            AggregateSagaManager.Tell(domainEvent);

            Logger.Debug("{0} just dispatched {1} to {2}", GetType().PrettyPrint(), domainEvent.GetType().PrettyPrint(), AggregateSagaManager.Path.Name);
            return(true);
        }
示例#24
0
        public static void Raise(IDomainEvent args)
        {
            var argsType = args.GetType();
            var method   = RaiseMethod.MakeGenericMethod(argsType);

            method.Invoke(null, new object[] { args });
        }
示例#25
0
        public bool Handle(IDomainEvent e, bool isReplay)
        {
            IsRebuilding = isReplay;

            var    eventType = e.GetType();
            string key       = eventType.FullName;

            MethodInvoker invoker = null;

            if (!_handlersCache.TryGetValue(key, out invoker))
            {
                var methodInfo = this.GetType().Method("On", new Type[] { eventType }, Flags.InstancePublic);
                if (methodInfo != null)
                {
                    invoker = methodInfo.DelegateForCallMethod();
                }
                _handlersCache.Add(key, invoker);
            }

            if (invoker != null)
            {
                invoker.Invoke(this, e);
                return(true);
            }

            return(false);
        }
示例#26
0
        private void ApplyEvent(IDomainEvent domainEvent)
        {
            _handlers[domainEvent.GetType()](domainEvent);

            // Each event bumps our version
            Version++;
        }
示例#27
0
        public async Task <EventResult> SaveEventAsync <TId>(string streamName, IDomainEvent <TId> @event)
        //where TId : IAggregateId
        {
            EnsureArg.IsNotNullOrEmpty(streamName, nameof(streamName));
            EnsureArg.IsNotNull(@event, nameof(@event));

            try
            {
                var eventData = new EventData(
                    @event.EventId,
                    @event.GetType().AssemblyQualifiedName,
                    true,
                    this.Serialize(@event),
                    Encoding.UTF8.GetBytes("{}")); // TODO: CorrelationId as metadata?

                var writeResult = await this.connection.AppendToStreamAsync(
                    streamName,
                    @event.AggregateVersion == EventSourcedAggregateRoot <TId> .NewVersion?ExpectedVersion.NoStream : @event.AggregateVersion,
                    eventData).AnyContext();

                // https://eventstore.com/docs/dotnet-api/optimistic-concurrency-and-idempotence/index.html
                return(new EventResult(writeResult.NextExpectedVersion));
            }
            catch (EventStoreConnectionException ex)
            {
                throw new EventStoreCommunicationException($"error while storing event {@event.EventId} for aggregate {@event.AggregateId}", ex);
            }
        }
示例#28
0
        public async Task <Result> StoreDomainEventAsync(IDomainEvent @event)
        {
            var evtType = @event.GetType();

            if (evtType.IsDefined(typeof(EventNotPersistedAttribute)))
            {
                return(Result.Ok());
            }
            try
            {
                if (_bufferInfo?.UseBuffer == true)
                {
                    await s_Lock.WaitAsync().ConfigureAwait(false);
                }
                using (var ctx = new EventStoreDbContext(_dbContextOptions, _archiveBehavior))
                {
                    await StoreEvent(@event, ctx).ConfigureAwait(false);

                    await ctx.SaveChangesAsync().ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                _logger.LogErrorMultilines("EFEventStore : Unable to persist an event.", e.ToString());
                return(Result.Fail());
            }
            finally
            {
                s_Lock.Release();
            }
            return(Result.Ok());
        }
        protected virtual bool Dispatch(IDomainEvent domainEvent)
        {
            DomainEventProxy.Tell(domainEvent);

            Logger.Debug("{0} just dispatched {1} to {2}", GetType().PrettyPrint(), domainEvent.GetType().PrettyPrint(), DomainEventProxy.Path.Name);
            return(true);
        }
示例#30
0
        private void HandleEvent(IDomainEvent domainEvent)
        {
            if (domainEvent.SourceId != _id)
            {
                var message = $"{nameof(domainEvent.SourceId)} is invalid.";
                throw new ArgumentException(message, nameof(domainEvent));
            }

            if (domainEvent.Version != _version + 1)
            {
                var message = $"{nameof(domainEvent.Version)} is invalid.";
                throw new ArgumentException(message, nameof(domainEvent));
            }

            Type eventType = domainEvent.GetType();
            Action <IDomainEvent> handler;

            if (_eventHandlers.TryGetValue(eventType, out handler))
            {
                handler.Invoke(domainEvent);
                _version = domainEvent.Version;
            }
            else
            {
                var message = $"Cannot handle event of type {eventType}.";
                throw new InvalidOperationException(message);
            }
        }
示例#31
0
        public async Task SaveEventAsync <TAggregate>(IDomainEvent @event) where TAggregate : IAggregateRoot
        {
            var aggregate = await _aggregates.FirstOrDefaultAsync(x => x.Id == @event.AggregateRootId);

            if (aggregate == null)
            {
                _aggregates.Add(new DomainAggregate
                {
                    Id   = @event.AggregateRootId,
                    Type = typeof(TAggregate).AssemblyQualifiedName
                });
            }

            var currentSequenceCount = await _events.CountAsync(x => x.AggregateId == @event.AggregateRootId);

            _events.Add(new DomainEvent
            {
                AggregateId    = @event.AggregateRootId,
                SequenceNumber = currentSequenceCount + 1,
                Type           = @event.GetType().AssemblyQualifiedName,
                Body           = JsonConvert.SerializeObject(@event),
                TimeStamp      = @event.TimeStamp
                                 //UserId = @event.UserId
            });

            await _context.SaveChangesAsync();
        }
示例#32
0
        public async Task SaveEventAsync <TAggregate>(IDomainEvent @event) where TAggregate : IAggregateRoot
        {
            using (var context = _contextFactory.Create())
            {
                var aggregate = await context.DomainAggregates.FirstOrDefaultAsync(x => x.Id == @event.AggregateRootId);

                if (aggregate == null)
                {
                    context.DomainAggregates.Add(new DomainAggregate
                    {
                        Id   = @event.AggregateRootId,
                        Type = typeof(TAggregate).AssemblyQualifiedName
                    });
                }

                var currentSequenceCount = await context.DomainEvents.CountAsync(x => x.DomainAggregateId == @event.AggregateRootId);

                context.DomainEvents.Add(new DomainEvent
                {
                    DomainAggregateId = @event.AggregateRootId,
                    SequenceNumber    = currentSequenceCount + 1,
                    Type      = @event.GetType().AssemblyQualifiedName,
                    Body      = JsonConvert.SerializeObject(@event),
                    TimeStamp = @event.TimeStamp,
                    UserId    = _httpContextAccessor.GetUserId(context)
                });

                await context.SaveChangesAsync();
            }
        }
示例#33
0
 public StoredEvent(string id, DateTime occuredOn, IDomainEvent domainEvent)
     : base(id)
 {
     OccuredOn = occuredOn;
     DomainEvent = domainEvent;
     TypeName = domainEvent.GetType().Name;
 }
示例#34
0
 public EventMessage(Guid aggregateId, int aggregateVersion, IDomainEvent @event)
 {
     this.AggregateId = aggregateId;
     this.AggregateVersion = aggregateVersion;
     this.Body = @event;
     this.BodyType = @event.GetType().AssemblyQualifiedName;
 }
示例#35
0
        /// <summary>
        /// Gets the domain event handlers.
        /// </summary>
        /// <param name="domainEvent">The domain event.</param>
        /// <returns></returns>
        public List <IDomainEventHandler> GetDomainEventHandlers(IDomainEvent domainEvent)
        {
            // Get the type of the event passed in
            String typeString = domainEvent.GetType().Name;

            // Lookup the list
            Boolean eventIsConfigured = this.EventHandlerConfiguration.ContainsKey(typeString);

            if (!eventIsConfigured)
            {
                // No handlers setup, return null and let the caller decide what to do next
                return(null);
            }

            String[] handlers = this.EventHandlerConfiguration[typeString];

            List <IDomainEventHandler> handlersToReturn = new List <IDomainEventHandler>();

            foreach (String handler in handlers)
            {
                List <KeyValuePair <String, IDomainEventHandler> > foundHandlers = this.DomainEventHandlers.Where(h => h.Key == handler).ToList();

                handlersToReturn.AddRange(foundHandlers.Select(x => x.Value));
            }

            return(handlersToReturn);
        }
示例#36
0
        public async Task <AppendResult> AppendEventAsync <TAggregateId>(IDomainEvent <TAggregateId> @event) where TAggregateId : IAggregateId
        {
            var paritionKey = @event.AggregateId.IdAsString();
            var partition   = new Partition(_table, paritionKey);

            var openResult = await Stream.TryOpenAsync(partition).ConfigureAwait(false);

            var stream = openResult.Found ? openResult.Stream : new Stream(partition);

            if (stream.Version != @event.AggregateVersion)
            {
                throw new EventStoreConcurrencyException();
            }

            try
            {
                var evtId         = EventId.From(@event.EventId.ToString());
                var evtProperties = new
                {
                    Id   = @event.EventId.ToString(),
                    Type = @event.GetType().AssemblyQualifiedName,
                    Data = JsonConvert.SerializeObject(@event)
                };

                var writeResult = await Stream.WriteAsync(stream, new EventData(EventId.From(evtId), EventProperties.From(evtProperties)))
                                  .ConfigureAwait(false);

                return(new AppendResult(writeResult.Events.ToList().Last().Version));
            }
            catch (ConcurrencyConflictException)
            {
                throw new EventStoreConcurrencyException();
            }
        }
 public void Apply(IDomainEvent evt)
 {
     if (_handlersByType.TryGetValue(evt.GetType(), out Action <IDomainEvent> apply))
     {
         apply(evt);
     }
 }
        protected virtual bool Dispatch(IDomainEvent domainEvent)
        {
            AggregateSagaManager.Tell(domainEvent);

            Logger.Debug($"{GetType().PrettyPrint()} just dispatched {domainEvent.GetType().PrettyPrint()} to {AggregateSagaManager}");
            return(true);
        }
 public void Dispatch(IDomainEvent e, string aggregateId)
 {
     var type = typeof(IEventHandler<>).MakeGenericType(e.GetType());
     var handlers = this.container.ResolveAll(type);
     foreach (var handler in handlers)
     {
         handler.AsDynamic().Handle(e, aggregateId);
     }
 }
        /// <summary>
        ///     Delegates the event and dispatches to all event handlers that subscribes to <see cref="IDomainEvent" />.
        /// </summary>
        /// <param name="domainEvent">Event to be dispatched.</param>
        public void Dispatch(IDomainEvent domainEvent)
        {
            Guard.ArgumentIsNotNull(domainEvent, nameof(domainEvent));

            var handlerType = typeof (IDomainEventHandler<>).MakeGenericType(domainEvent.GetType());
            dynamic handlers = _container.GetAllInstances(handlerType);

            foreach (var handler in handlers)
                handler.Handle((dynamic) domainEvent);
        }
 // ----- Utils
 private static OrderEvent ConvertToPersistentEvent(IDomainEvent domainEvent)
 {
     return new OrderEvent
     {
         AggregateId = domainEvent.AggregateId,
         CreationDate = DateTime.Now,
         Name = domainEvent.GetType().ToString(),
         Content = JsonConvert.SerializeObject(domainEvent)
     };
 }
示例#42
0
        public virtual void Apply(IDomainEvent e)
        {
            var eventType = e.GetType();
            var castedEvent = Convert.ChangeType(e, eventType);

            var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            var methods = GetType().GetMethods(bindingFlags)
                .Where(x => x.GetParameters().Count() > 0)
                .Where(x => x.Name.Contains("Apply"))
                .Where(x => x.GetParameters()[0].ParameterType == eventType)
                .ToList();

            if (methods.Count() <= 0)
                throw new ArgumentException(string.Format("Event '{0}' cannot be processed by this aggregate", e.GetType()));

            if (e.IsValid())
                methods.First().Invoke(this, bindingFlags, null, new[] {castedEvent}, null);
        }
示例#43
0
        private static IEnumerable<object> HandleEvent(IDomainEvent evnt, Type subscriberType)
        {
            IList<object> results = new List<object>();

            var eventHandlers = DomainInitializer.Current.GetEventHandlers(subscriberType).Where(eventHandler => IsEventHandler(eventHandler, evnt.GetType()));
            foreach (var eventHandler in eventHandlers)
            {
                ExecuteEventHandler(eventHandler, GetSubscriber(subscriberType), evnt, ref results);
            }

            return results;
        }
示例#44
0
 public static void Publish(IDomainEvent evnt)
 {
     foreach (var subscriberType in EventSubscriberMappingStore.Current.GetSubscriberTypesList(evnt.GetType()))
     {
         foreach (var result in HandleEvent(evnt, subscriberType))
         {
             if (result != null)
             {
                 evnt.Results.Add(result);
             }
         }
     }
 }
示例#45
0
 public void Publish(IDomainEvent evnt)
 {
     foreach (var subscriberType in DomainInitializer.Current.GetSubscriberTypesList(evnt.GetType()))
     {
         foreach (var result in HandleEvent(evnt, subscriberType))
         {
             if (result != null)
             {
                 evnt.Results.Add(result);
             }
         }
     }
 }
示例#46
0
        public void Publish(IDomainEvent theEvent)
        {
            if (theEvent == null)
            {
                throw new ArgumentNullException("The event should not be null");
            }

            var handlerType = typeof(IEventHandler<>).MakeGenericType(theEvent.GetType());
            var handlers = this.container.GetAllInstances(handlerType);
            foreach (dynamic handler in handlers)
            {
                handler.Handle((dynamic)theEvent);
            }
        }
示例#47
0
		public void SaveEvent(IDomainEvent @event)
		{
			var eventLogEntry = new EventLog
			{
				EventId = @event.Id,
				EventProviderId = @event.AggregateId,
				Version = @event.Version,
				Type = @event.GetType().AssemblyQualifiedName,
				User = @event.ByUser,
				DateHappened = @event.DateHappened,
				JSonDomainEvent = @event.GetJSonSerialisation(),
			};

			entityRepository.Save(eventLogEntry);
		}
示例#48
0
        public static void Dispatch(IDomainEvent domainEvent)
        {
            foreach (Type handlerType in _handlers)
            {
                bool canHandleEvent = handlerType.GetInterfaces()
                    .Any(x => x.IsGenericType
                        && x.GetGenericTypeDefinition() == typeof(IHandler<>)
                        && x.GenericTypeArguments[0] == domainEvent.GetType());

                if (canHandleEvent)
                {
                    dynamic handler = Activator.CreateInstance(handlerType);
                    handler.Handle((dynamic)domainEvent);
                }
            }
        }
示例#49
0
        public void Dispatch(IDomainEvent evnt, EventDispatchingContext context)
        {
            Check.Argument.IsNotNull(evnt, "evnt");
            Check.Argument.IsNotNull(context, "context");

            foreach (var method in _handlerRegistry.FindHandlerMethods(evnt.GetType()))
            {
                var awaitCommit = TypeUtil.IsAttributeDefinedInMethodOrDeclaringClass(method, typeof(AwaitCommittedAttribute));

                if (awaitCommit && !context.WasUnitOfWorkCommitted
                    || !awaitCommit && context.WasUnitOfWorkCommitted)
                {
                    continue;
                }

                _handlerInvoker.Invoke(evnt, method, context);
            }
        }
示例#50
0
        public bool EventIsOwnedByEntity(IDomainEvent 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);
            }
        }
示例#51
0
        /// <summary>
        /// 根据给定的领域事件对象创建并初始化领域事件数据传输对象。
        /// </summary>
        /// <param name="acDomain"></param>
        /// <param name="entity">领域事件对象。</param>
        /// <returns>领域事件数据传输对象。</returns>
        public static DomainEventDataObject FromDomainEvent(this IAcDomain acDomain, IDomainEvent entity)
        {
            var serializer = acDomain.RetrieveRequiredService<IDomainEventSerializer>();
            var obj = new DomainEventDataObject
            {
                Branch = entity.Branch,
                Data = serializer.Serialize(entity),
                Id = entity.Id,
                AssemblyQualifiedEventType =
                    string.IsNullOrEmpty(entity.AssemblyQualifiedEventType)
                        ? entity.GetType().AssemblyQualifiedName
                        : entity.AssemblyQualifiedEventType,
                Timestamp = entity.Timestamp,
                Version = entity.Version,
                SourceId = entity.Source.Id,
                AssemblyQualifiedSourceType = entity.Source.GetType().AssemblyQualifiedName
            };

            return obj;
        }
示例#52
0
        private void apply(Type eventType, IDomainEvent domainEvent)
        {
            List<Action<object, object>> handlers;

            if (!_registeredEventHandlers.TryGetValue(domainEvent.GetType(), out handlers))
                throw new UnregisteredDomainEventException(string.Format("The requested domain event '{0}' is not registered in '{1}'", eventType.FullName, GetType().FullName));

            foreach (var handler in handlers)
            {
                handler(_proxy, domainEvent);
            }
        }
示例#53
0
        private void apply(Type eventType, IDomainEvent domainEvent)
        {
            List<Action<object, Dictionary<string, object>>> handlers;
            if (!_registeredEventHandlers.TryGetValue(domainEvent.GetType(), out handlers))
                throw new UnregisteredDomainEventException(string.Format("The requested domain event '{0}' is not registered in '{1}'", eventType.FullName, GetType().FullName));

            handlers.ForEach(handler => handler(domainEvent, _internalState));
        }
示例#54
0
 /// <summary>
 /// Creates and initializes the domain event data object from the given domain event.
 /// </summary>
 /// <param name="entity">The domain event instance from which the domain event data object
 /// is created and initialized.</param>
 /// <returns>The initialized data object instance.</returns>
 public static DomainEventDataObject FromDomainEvent(IDomainEvent entity)
 {
     IDomainEventSerializer serializer = GetDomainEventSerializer();
     DomainEventDataObject obj = new DomainEventDataObject();
     obj.Branch = entity.Branch;
     obj.Data = serializer.Serialize(entity);
     obj.ID = entity.ID;
     if (string.IsNullOrEmpty(entity.AssemblyQualifiedEventType))
         obj.AssemblyQualifiedEventType = entity.GetType().AssemblyQualifiedName;
     else
         obj.AssemblyQualifiedEventType = entity.AssemblyQualifiedEventType;
     obj.Timestamp = entity.Timestamp;
     obj.Version = entity.Version;
     obj.SourceID = entity.Source.ID;
     obj.AssemblyQualifiedSourceType = entity.Source.GetType().AssemblyQualifiedName;
     return obj;
 }
示例#55
0
        private bool DispatchEventToHandler(IDomainEvent evnt, IEventHandler handler)
        {
            try
            {
                var eventHandlerTypeCode = _eventHandlerTypeCodeProvider.GetTypeCode(handler.GetInnerEventHandler().GetType());
                if (_eventHandleInfoCache.IsEventHandleInfoExist(evnt.Id, eventHandlerTypeCode)) return true;
                if (_eventHandleInfoStore.IsEventHandleInfoExist(evnt.Id, eventHandlerTypeCode)) return true;

                handler.Handle(evnt);
                _eventHandleInfoStore.AddEventHandleInfo(evnt.Id, eventHandlerTypeCode);
                _eventHandleInfoCache.AddEventHandleInfo(evnt.Id, eventHandlerTypeCode);
                return true;
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("Exception raised when [{0}] handling [{1}].", handler.GetInnerEventHandler().GetType().Name, evnt.GetType().Name), ex);
                return false;
            }
        }
示例#56
0
 public bool CanHandleEvent(IDomainEvent e)
 {
     return e.GetType() == eventType;
 }
 private static string GetErrorMessage(EntityBase entity, IDomainEvent @event)
 {
     return String.Format("An error occured while invoking event handler {0} on {1}", @event.GetType().FullName, entity.GetType().FullName);
 }
 public AmbigousHandlerException(IDomainEvent evt) : base(evt.GetType().AssemblyQualifiedName)
 {
     
 }
 /// <summary>
 /// Checks whether the specified domain event could be handled by the current handler.
 /// </summary>
 /// <param name="domainEvent">The domain event to be checked.</param>
 /// <returns>True if the specified domain event can be handled by the current handler, otherwise false.</returns>
 public bool CanHandle(IDomainEvent domainEvent)
 {
     return domainEventType.Equals(domainEvent.GetType());
 }
 private static string GetErrorMessage(EntityBase entity, IDomainEvent @event)
 {
     return String.Format("Unable to locate an event handler for {0} on {1}", @event.GetType().FullName, entity.GetType().FullName);
 }