Example #1
0
        public TAggregate Get <TAggregate>(Guid aggregateId) where TAggregate : IAggregateRoot
        {
            List <EventSourcingDescription> eventsHistory;
            var typeAggregate = typeof(TAggregate);

            using (var db = new EventSourcingDbContext())
            {
                eventsHistory = db.EventSoucings.AsNoTracking()
                                .Where(i => i.AggregateId.Equals(aggregateId) &&
                                       i.AggregateType.Equals(typeAggregate.AssemblyQualifiedName, StringComparison.OrdinalIgnoreCase)
                                       ).OrderBy(i => i.Version).ThenBy(i => i.CreatedDate).ToList();
            }

            if (eventsHistory.Any() == false)
            {
                throw new AggregateNotFoundException(
                          $"Not found AggregateType: {typeAggregate.FullName} with Id: {aggregateId}");
            }

            TAggregate a = (TAggregate)Activator.CreateInstance(typeAggregate);

            List <IEvent> convertedEvents = new List <IEvent>();

            foreach (var e in eventsHistory)
            {
                try
                {
                    var jobj       = JsonConvert.DeserializeObject(e.EventData) as Newtonsoft.Json.Linq.JObject;
                    var objectType = Type.GetType(e.EventType, false, true);

                    if (objectType == null || jobj == null)
                    {
                        continue;
                    }

                    var o = jobj.ToObject(objectType);
                    convertedEvents.Add((IEvent)o);
                }
                catch (Exception ex)
                {
                    //todo:should consider what should do
                    throw new AggregateHistoryBuilderException($"Check event types for AggregateType: {typeof(TAggregate).FullName} with Id: {aggregateId}", ex);
                }
            }

            a.LoadFromHistory(convertedEvents);

            return(a);
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="aggregate"></param>
        /// <param name="expectedVersion">-1: automatic get lastest version</param>
        public void Save <TAggregate>(TAggregate aggregate, int expectedVersion = -1) where TAggregate : IAggregateRoot
        {
            if (Guid.Empty.Equals(aggregate.Id))
            {
                throw new ArgumentNullException($"Aggregate with Id null");
            }

            List <EventSourcingDescription> eventChanges = new List <EventSourcingDescription>();

            var aggregateChangeds = aggregate.Changes.ToList();
            var xaggregateId      = aggregate.Id;

            #region check lastest version

            long lastVersion = 0;
            using (var db = new EventSourcingDbContext())
            {
                lastVersion = db.EventSoucings
                              .AsNoTracking()
                              .Where(i => i.AggregateId.Equals(xaggregateId) &&
                                     i.AggregateType.Equals(typeof(TAggregate).AssemblyQualifiedName,
                                                            StringComparison.OrdinalIgnoreCase))
                              .Select(i => i.Version)
                              .OrderByDescending(i => i)
                              .FirstOrDefault();
            }

            if (expectedVersion >= 0)
            {
                if (lastVersion != expectedVersion)
                {
                    throw new AggregateConflickVersionException(
                              string.Format(
                                  "Version conflick for AggregateType: {0} with Id: {1} Latest version: {2} Expected version: {3}"
                                  , aggregate.GetType().FullName, aggregate.Id, lastVersion, expectedVersion));
                }
                lastVersion = expectedVersion;
            }
            #endregion

            foreach (var e in aggregateChangeds)
            {
                lastVersion++;
                e.Version = lastVersion;

                if (e.PublishedEventId == null || e.PublishedEventId == Guid.Empty)
                {
                    e.PublishedEventId = Guid.NewGuid();
                }

                //build event data add to event store db
                eventChanges.Add(new EventSourcingDescription()
                {
                    EsdId         = e.PublishedEventId.Value,
                    AggregateId   = aggregate.Id,
                    AggregateType = typeof(TAggregate).AssemblyQualifiedName,
                    EventData     = JsonConvert.SerializeObject(e),
                    EventType     = e.GetType().AssemblyQualifiedName,
                    Version       = lastVersion,
                    CreatedDate   = DateTime.UtcNow
                });
            }

            //save to event store db
            using (var db = new EventSourcingDbContext())
            {
                db.EventSoucings.AddRange(eventChanges);
                db.SaveChanges();
            }

            //publish event
            foreach (var e in aggregateChangeds)
            {
                //todo:publish event
                //DistributedServices.Publish(new DistributedCommand(e), true);
                EventPublisher.Publish(e);
            }
        }