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); }
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()); }
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); } }
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); }
public object ResolveParameterValue(IMessage message) { if (!CurrentUnitOfWork.IsStarted) { return(null); } return(CurrentUnitOfWork.Get()); }
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); }
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); }
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); }
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); }
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; }