Ejemplo n.º 1
0
        /// <summary>
        /// Creates the aggregate root.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="entityEventSource">The entity event source.</param>
        /// <param name="domainEventErroneoAction">The domainEventErroneoAction.</param>
        /// <returns></returns>
        private AggregateRoot <TEntity, TId> CreateAggregateRoot(TId id, EntityEventSource <TEntity, TId> entityEventSource, Action <AggregateRoot <TEntity, TId>, IDomainEvent <TEntity> > domainEventErroneoAction = null)
        {
            Logger.Debug(string.Format("Creando la entidad {1} {0}", id, typeof(TEntity).Name));

            var root = entityEventSource.SnapShot ?? new TEntity {
                Id = id, Version = 0
            };

            var fsmDecorator = FiniteStateMachineFactory.Create <TEntity, TId>(_fsmConfigurator, root, entityEventSource.State);
            var aggregate    = new AggregateRoot <TEntity, TId>(_repository, fsmDecorator, _applierEvents)
            {
                Logger = Logger
            };

            aggregate.DomainEventErroneo += (sender, args) =>
            {
                if (domainEventErroneoAction != null)
                {
                    domainEventErroneoAction.Invoke((AggregateRoot <TEntity, TId>)sender, args.Event);
                }
            };

            Logger.Debug(string.Format("Reconstruyendo la entidad {0}", id));
            aggregate.ApplyEvents(entityEventSource.Events);

            Logger.Debug(string.Format("Estado de la entidad {0}: {1}", id, aggregate.State));

            return(aggregate);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Finds the and modify.
        /// </summary>
        /// <param name="id"> </param>
        /// <param name="event">The @event.</param>
        /// <returns></returns>
        public EntityEventSource <TEntity, TId> AddEvent(TId id, IDomainEvent <TEntity> @event)
        {
            _repository.Create(new EntityEventSource <TEntity, TId> {
                Id = id, Status = "Ready"
            });
            EntityEventSource <TEntity, TId> entity = null;

            SpinWait.SpinUntil(() =>
            {
                var query = Query.And(Query.EQ("_id", BsonDocumentWrapper.Create(id)),
                                      Query.Or(Query.EQ("Status", "Ready"),
                                               Query.LTE("ProcessingAt",
                                                         new BsonDateTime(
                                                             DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(_timeOut)))),
                                               Query.EQ("ProcessingBy",
                                                        Thread.CurrentThread.ManagedThreadId.ToString(
                                                            CultureInfo.InvariantCulture))));

                entity = _repository.FindAndModify
                         (
                    query,
                    x => ((UpdateBuilder)x.GetUpdateBuilder())
                    .Push("Events", BsonDocumentWrapper.Create(@event))
                    .Set("Status", new BsonString("Processing"))
                    .Set("ProcessingAt", new BsonDateTime(DateTime.UtcNow))
                    .Set("ProcessingBy", new BsonString(Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture))),
                    false,
                    true
                         );
                return(entity != null);
            });

            return(entity);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the and apply event.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="events">The @event.</param>
        /// <param name="domainEventErroneoAction">The domain event erroneo action.</param>
        /// <returns></returns>
        public AggregateRoot <TEntity, TId> GetAndApplyEvents(TId id, IEnumerable <IDomainEvent <TEntity> > events, Action <AggregateRoot <TEntity, TId>, IDomainEvent <TEntity> > domainEventErroneoAction)
        {
            EntityEventSource <TEntity, TId> entityEventSource = null;

            foreach (var domainEvent in events)
            {
                entityEventSource = _repository.AddEvent(id, domainEvent);
            }
            return(CreateAggregateRoot(id, entityEventSource, domainEventErroneoAction));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds the and modify.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="events">The events.</param>
        /// <returns></returns>
        public EntityEventSource <TEntity, long> AddEvent(long id, IEnumerable <IDomainEvent <TEntity> > events)
        {
            if (NHibernateHelper.CurrentSession.Get <EntityEventSourceWrapper>(id) == null)
            {
                NHibernateHelper.CurrentSession.Save(new EntityEventSourceWrapper {
                    Id = id, Status = "Ready"
                });
                NHibernateHelper.CurrentSession.Flush();
            }

            EntityEventSource <TEntity, long> entity = null;

            SpinWait.SpinUntil(() =>
            {
                var criterion = Restrictions.Or(Restrictions.Or(Restrictions.Eq("Status", "Ready"),
                                                                Restrictions.Le("ProcessingAt", DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(_timeOut)))),
                                                Restrictions.Eq("ProcessingBy", Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture)));

                var query = Restrictions.And(Restrictions.Eq("Id", id), criterion);
                var entitySourceWrapper = (EntityEventSourceWrapper)NHibernateHelper.CurrentSession
                                          .CreateCriteria <EntityEventSourceWrapper>()
                                          .Add(query).UniqueResult();

                if (entitySourceWrapper != null)
                {
                    entitySourceWrapper.Status       = "Processing";
                    entitySourceWrapper.ProcessingAt = DateTime.UtcNow;
                    entitySourceWrapper.ProcessingBy = Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture);

                    foreach (var domainEvent in events)
                    {
                        BsonClassMap.IsClassMapRegistered(domainEvent.GetType());

                        var eventWrapper = new EventWrapper
                        {
                            Type    = domainEvent.GetType().Name,
                            Data    = domainEvent.ToBson(),
                            Version = domainEvent.Version
                        };
                        entitySourceWrapper.AddEvent(eventWrapper);
                    }


                    NHibernateHelper.CurrentSession.Update(entitySourceWrapper);
                    NHibernateHelper.CurrentSession.Flush();

                    entity = new EntityEventSource <TEntity, long>();
                    Translator.Instance.TranslateToDomain(entity, entitySourceWrapper);
                }

                return(entity != null);
            });

            return(entity);
        }
Ejemplo n.º 5
0
        public void TranslateToDomain <TEntity>(EntityEventSource <TEntity, long> domain, EntityEventSourceWrapper entity)
            where TEntity : IVersionableEntity <long>, new()
        {
            domain.Id           = entity.Id;
            domain.State        = entity.State;
            domain.Status       = entity.Status;
            domain.ProcessingAt = entity.ProcessingAt;
            domain.ProcessingBy = entity.ProcessingBy;
            if (entity.SnapShot != null)
            {
                domain.SnapShot = (TEntity)BsonSerializer.Deserialize(entity.SnapShot, typeof(TEntity));
            }

            foreach (var eventWrapper in entity.Events)
            {
                var registeredClassMaps = BsonClassMap.GetRegisteredClassMaps();
                var bsonClassMap        = registeredClassMaps.First(map => map.Discriminator == eventWrapper.Type);
                var @event = BsonSerializer.Deserialize(eventWrapper.Data, bsonClassMap.ClassType);
                domain.Events.Add((IDomainEvent <TEntity>)@event);
            }
        }