public object Handle(IMessage message, object target)
        {
            var childEntity = _childEntityResolver.Invoke((ICommandMessage)message, target);

            if (childEntity == null)
            {
                throw new AggregateEntityNotFoundException(
                          "Aggregate cannot handle this command, as there is no entity instance to forward it to."
                          );
            }
            var interceptors = _childHandlerInterceptors
                               .Where(chi => chi.CanHandle(message))
                               .OrderBy(x => x.Priority)
                               .Select(chi => new AnnotatedCommandHandlerInterceptor(chi, childEntity))
                               .ToList();

            object result;

            if (interceptors.IsEmpty())
            {
                result = _childHandler.Handle(message, childEntity);
            }
            else
            {
                result = new DefaultInterceptorChain(CurrentUnitOfWork.Get(),
                                                     interceptors.GetEnumerator(),
                                                     MessageHandler <ICommandMessage> .Create(m => _childHandler.Handle(message, childEntity))).Proceed();
            }
            return(result);
        }
示例#2
0
        private void PrepareForCommit(A aggregate)
        {
            CurrentUnitOfWork.Get().OnPrepareCommit(u =>
            {
                // if the aggregate isn't "managed" anymore, it means its state was invalidated by a rollback
                if (ManagedAggregates(CurrentUnitOfWork.Get()).ContainsValue(aggregate))
                {
                    if (aggregate.IsDeleted)
                    {
                        DoDelete(aggregate);
                    }
                    else
                    {
                        DoSave(aggregate);
                    }

                    if (aggregate.IsDeleted)
                    {
                        PostDelete(aggregate);
                    }
                    else
                    {
                        PostSave(aggregate);
                    }
                }
                else
                {
                    ReportIllegalState(aggregate);
                }
            });
        }
        private void LockSagaAccess(string sagaIdentifier)
        {
            var unitOfWork = CurrentUnitOfWork.Get();
            var @lock      = _lockFactory.ObtainLock(sagaIdentifier);

            unitOfWork.Root().OnCleanup(u => @lock.Dispose());
        }
示例#4
0
        public object Handle(ICommandMessage msg)
        {
            return(ExecuteWithResult(() =>
            {
                var interceptors = _inspector.CommandHandlerInterceptors
                                   .Where(chi => chi.CanHandle(msg))
                                   .OrderBy(x => x.Priority)
                                   .Select(x => new AnnotatedCommandHandlerInterceptor(x, _aggregateRoot))
                                   .ToList();
                var handler = _inspector.CommandHandlers.GetValueOrDefault(msg.CommandName);
                object result;
                if (interceptors.IsEmpty())
                {
                    result = handler.Handle(msg, _aggregateRoot);
                }
                else
                {
                    result = new DefaultInterceptorChain(CurrentUnitOfWork.Get(), interceptors.GetEnumerator(), MessageHandler <ICommandMessage> .Create(m => handler.Handle(msg, _aggregateRoot))).Proceed();
                }

                if (_aggregateRoot == null)
                {
                    _aggregateRoot = (T)result;
                    return this.IdentifierAsString();
                }

                return result;
            }));
        }
 protected override ISaga <T> DoCreateInstance(string sagaIdentifier, Func <T> sagaFactory)
 {
     try
     {
         var unitOfWOrk  = CurrentUnitOfWork.Get();
         var processRoot = unitOfWOrk.Root();
         var sagaRoot    = sagaFactory.Invoke();
         var saga        = new AnnotatedSaga <T>(sagaIdentifier, new HashSet <AssociationValue>(), sagaRoot, null, _sagaModel);
         UnsavedSagasResource(processRoot).Add(sagaIdentifier);
         unitOfWOrk.OnPrepareCommit(u =>
         {
             if (saga.IsActive)
             {
                 StoreSaga(saga);
                 saga.AssociationValues.Commit();
                 UnsavedSagasResource(processRoot).Remove(sagaIdentifier);
             }
         });
         _managedSagas[sagaIdentifier] = saga;
         processRoot.OnCleanup(u => _managedSagas.Remove(sagaIdentifier));
         return(saga);
     }
     catch (Exception e)
     {
         throw new SagaCreationException("An error occurred while attempting to create a new managed instance", e);
     }
 }
示例#6
0
        public void Publish(List <IEventMessage> events)
        {
            var ingested = events.Select(x => _messageMonitor.OnMessageIngested(x)).ToList();

            if (CurrentUnitOfWork.IsStarted)
            {
                var unitOfWork = CurrentUnitOfWork.Get();
                Assert.State(!unitOfWork.Phase.IsAfter(Phase.PREPARE_COMMIT),
                             () => "It is not allowed to publish events when the current Unit of Work has already been " +
                             "committed. Please start a new Unit of Work before publishing events.");
                Assert.State(!unitOfWork.Root().Phase.IsAfter(Phase.PREPARE_COMMIT),
                             () => "It is not allowed to publish events when the root Unit of Work has already been " +
                             "committed.");

                unitOfWork.AfterCommit(u => ingested.ForEach(x => x.ReportSuccess()));
                unitOfWork.OnRollback(u => ingested.ForEach(m => m.ReportFailure(u.ExecutionResult.Exception)));

                EventsQueue(unitOfWork).AddRange(events);
            }
            else
            {
                try
                {
                    PrepareCommit(Intercept(events));
                    Commit(events);
                    AfterCommit(events);
                    ingested.ForEach(x => x.ReportSuccess());
                }
                catch (Exception e)
                {
                    ingested.ForEach(m => m.ReportFailure(e));
                    throw;
                }
            }
        }
 public static void Initialize <T, R>(IInterceptorChain interceptorChain)
     where T : IMessage <R> where R : class
 {
     Assert.State(CurrentUnitOfWork <T, R> .IsStarted(),
                  () => "An active Unit of Work is required for injecting interceptor chain");
     CurrentUnitOfWork <T, R> .Get().Resources().Add(INTERCEPTOR_CHAIN_EMITTER_KEY, interceptorChain);
 }
        protected override ISaga <T> DoLoad(string sagaIdentifier)
        {
            var unitOfWork  = CurrentUnitOfWork.Get();
            var processRoot = unitOfWork.Root();

            var loadedSaga = _managedSagas.ComputeIfAbsent(sagaIdentifier, id =>
            {
                var result = DoLoadSaga(sagaIdentifier);
                if (result != null)
                {
                    processRoot.OnCleanup(u => _managedSagas.Remove(id));
                }

                return(result);
            });

            if (loadedSaga != null && UnsavedSagasResource(processRoot).Add(sagaIdentifier))
            {
                unitOfWork.OnPrepareCommit(u =>
                {
                    UnsavedSagasResource(processRoot).Remove(sagaIdentifier);
                    Commit(loadedSaga);
                });
            }

            return(loadedSaga);
        }
示例#9
0
        public object ResolveParameterValue(IMessage message)
        {
            if (!CurrentUnitOfWork.IsStarted)
            {
                return(null);
            }

            return(CurrentUnitOfWork.Get());
        }
示例#10
0
        public IAggregate <T> Load(string aggregateIdentifier, long?expectedVersion)
        {
            var uow        = CurrentUnitOfWork.Get();
            var aggregates = ManagedAggregates(uow);
            A   aggregate  =
                aggregates.ComputeIfAbsent(aggregateIdentifier, s => DoLoad(aggregateIdentifier, expectedVersion));

            uow.OnRollback(u => aggregates.Remove(aggregateIdentifier));
            ValidateOnLoad(aggregate, expectedVersion);
            PrepareForCommit(aggregate);

            return(aggregate);
        }
示例#11
0
        public IAggregate <T> NewInstance(Func <T> factoryMethod)
        {
            A aggregate = DoCreateNew(factoryMethod);

            Assert.IsTrue(AggregateModel.EntityClass.IsAssignableFrom(aggregate.RootType), () => "Unsuitable aggregate for this repository: wrong type");
            var uow        = CurrentUnitOfWork.Get();
            var aggregates = ManagedAggregates(uow);

            IsTrue(aggregates.PutIfAbsent(aggregate.IdentifierAsString(), aggregate) == null, () => "The Unit of Work already has an Aggregate with the same identifier");
            uow.OnRollback(u => aggregates.Remove(aggregate.IdentifierAsString()));
            PrepareForCommit(aggregate);
            return(aggregate);
        }
示例#12
0
        protected List <IEventMessage> QueuedMessages()
        {
            if (!CurrentUnitOfWork.IsStarted)
            {
                return(new List <IEventMessage>());
            }
            var messages = new List <IEventMessage>();

            for (var uow = CurrentUnitOfWork.Get(); uow != null; uow = uow.Parent.OrElse(null))
            {
                messages.InsertRange(0, uow.GetOrDefaultResource(_eventsKey, new List <IEventMessage>()));
            }
            return(messages);
        }
示例#13
0
        public AbstractUnitOfWorkTest()
        {
            var serviceLocator = Substitute.For <IServiceLocator>();
            var logger         = Substitute.For <ILogger <AbstractUnitOfWork> >();

            serviceLocator.GetInstance <ILogger <AbstractUnitOfWork> >().Returns(logger);

            CommonServiceLocator.ServiceLocator.SetLocatorProvider(() => serviceLocator);
            while (CurrentUnitOfWork.IsStarted)
            {
                CurrentUnitOfWork.Get().Rollback();
            }

            _subject = Substitute.ForPartsOf <DefaultUnitOfWork>(new GenericEventMessage <string>("Input 1"));
            //_subject.ToString().Returns("unitOfWork");
            _phaseTransitoins = new List <PhaseTransition>();
            RegisterListeners(_subject);
        }
        public object?Handle(IMessage <object> message, TParent target)
        {
            TChild childEntity = _childEntityResolver((ICommandMessage <object>)message, target);

            if (childEntity == null)
            {
                throw new AggregateEntityNotFoundException(
                          "Aggregate cannot handle this command, as there is no entity instance to forward it to."
                          );
            }

            IList <AnnotatedCommandHandlerInterceptor <TChild, object> > interceptors =
                _childHandlingInterceptors
                .Where(messageHandlingMember => messageHandlingMember.CanHandle(message))
                .OrderByDescending((messageHandlingMember) => messageHandlingMember.Priority())
                .Select(messageHandlingMember =>
                        new AnnotatedCommandHandlerInterceptor <TChild, object>(messageHandlingMember, childEntity)
                        )
                .ToList();

            object?result;

            if (interceptors.Count == 0)
            {
                result = _childHandler.Handle(message, childEntity);
            }
            else
            {
                result = new DefaultInterceptorChain <IMessage <object>, object>(
                    (IUnitOfWork <ICommandMessage <object>, object>)CurrentUnitOfWork <IMessage <object>, object>
                    .Get(),
                    interceptors.Cast <IMessageHandlerInterceptor <IMessage <object>, object> >().ToList(),
                    new MessageHandler <IMessage <object>, object>(
                        m => _childHandler.Handle(message, childEntity) !
                        )
                    ).Proceed();
            }

            return(result);
        }
示例#15
0
 public static void Initialize(IConflictResolver conflictResolver)
 {
     Assert.State(CurrentUnitOfWork.IsStarted, () => "An active Unit of Work is required for conflict resolution");
     CurrentUnitOfWork.Get().GetOrComputeResource(CONFLICT_RESOLUTION_KEY, key => conflictResolver);
 }
 public static void Initialize(IInterceptorChain interceptorChain)
 {
     Assert.State(CurrentUnitOfWork.IsStarted,
                  () => "An active Unit of Work is required for injecting interceptor chain");
     CurrentUnitOfWork.Get().Resources[INTERCEPTOR_CHAIN_EMITTER_KEY] = interceptorChain;
 }