コード例 #1
0
        public void Should_have_passed_through_correct_state()
        {
            HandlerInvocationCache.CacheMethodForHandler(typeof(StubHandler), typeof(StubTimeoutState));
            var handler   = new StubHandler();
            var stubState = new StubTimeoutState();

            HandlerInvocationCache.InvokeTimeout(handler, stubState);
            Assert.AreEqual(stubState, handler.HandledState);
        }
コード例 #2
0
        /// <summary>
        /// Get Dispatcher
        /// </summary>
        /// <param name="messageHandlerType">Type of the message Handler</param>
        /// <param name="builder">Builder</param>
        /// <param name="message">Message</param>
        /// <returns>Saga Dispatcher</returns>
        public IEnumerable <Action> GetDispatcher(Type messageHandlerType, IBuilder builder, object message)
        {
            var entitiesHandled  = new List <IContainSagaData>();
            var sagaTypesHandled = new List <Type>();

            foreach (var finder in GetFindersFor(message, builder))
            {
                var  sagaEntityIsPersistent = true;
                var  sagaEntity             = UseFinderToFindSaga(finder, message);
                Type sagaType;

                if (sagaEntity == null)
                {
                    sagaType = Features.Sagas.GetSagaTypeToStartIfMessageNotFoundByFinder(message, finder);
                    if (sagaType == null)
                    {
                        continue;
                    }

                    if (sagaTypesHandled.Contains(sagaType))
                    {
                        continue; // don't create the same saga type twice for the same message
                    }
                    sagaEntity = CreateNewSagaEntity(sagaType);

                    sagaEntityIsPersistent = false;
                }
                else
                {
                    if (entitiesHandled.Contains(sagaEntity))
                    {
                        continue; // don't call the same saga twice
                    }
                    sagaType = Features.Sagas.GetSagaTypeForSagaEntityType(sagaEntity.GetType());
                }

                if (messageHandlerType.IsAssignableFrom(sagaType))
                {
                    yield return () =>
                           {
                               var saga = (ISaga)builder.Build(sagaType);

                               saga.Entity = sagaEntity;

                               try
                               {
                                   SagaContext.Current = saga;

                                   if (IsTimeoutMessage(message))
                                   {
                                       HandlerInvocationCache.InvokeTimeout(saga, message);
                                   }
                                   else
                                   {
                                       HandlerInvocationCache.InvokeHandle(saga, message);
                                   }

                                   if (!saga.Completed)
                                   {
                                       if (!sagaEntityIsPersistent)
                                       {
                                           Persister.Save(saga.Entity);
                                       }
                                       else
                                       {
                                           Persister.Update(saga.Entity);
                                       }
                                   }
                                   else
                                   {
                                       if (sagaEntityIsPersistent)
                                       {
                                           Persister.Complete(saga.Entity);
                                       }

                                       if (saga.Entity.Id != Guid.Empty)
                                       {
                                           NotifyTimeoutManagerThatSagaHasCompleted(saga);
                                       }
                                   }

                                   LogIfSagaIsFinished(saga);
                               }
                               finally
                               {
                                   SagaContext.Current = null;
                               }
                           }
                }
                ;

                sagaTypesHandled.Add(sagaType);
                entitiesHandled.Add(sagaEntity);
            }

            if (entitiesHandled.Count == 0)
            {
                yield return () =>
                       {
                           logger.InfoFormat("Could not find a saga for the message type {0} with id {1}. Going to invoke SagaNotFoundHandlers.", message.GetType().FullName, Bus.CurrentMessageContext.Id);

                           foreach (var handler in builder.BuildAll <IHandleSagaNotFound>())
                           {
                               logger.DebugFormat("Invoking SagaNotFoundHandler: {0}",
                                                  handler.GetType().FullName);
                               handler.Handle(message);
                           }
                       }
            }
            ;
        }

        IContainSagaData CreateNewSagaEntity(Type sagaType)
        {
            var sagaEntityType = Features.Sagas.GetSagaEntityTypeForSagaType(sagaType);

            if (sagaEntityType == null)
            {
                throw new InvalidOperationException("No saga entity type could be found for saga: " + sagaType);
            }

            var sagaEntity = (IContainSagaData)Activator.CreateInstance(sagaEntityType);

            sagaEntity.Id = CombGuid.Generate();

            if (Bus.CurrentMessageContext.ReplyToAddress != null)
            {
                sagaEntity.Originator = Bus.CurrentMessageContext.ReplyToAddress.ToString();
            }
            sagaEntity.OriginalMessageId = Bus.CurrentMessageContext.Id;

            return(sagaEntity);
        }