public TProjector GetById <TProjector, TViewModel>(IIdentity id, Int32 to)
            where TProjector : Projector <TViewModel>
            where TViewModel : BaseAggregateQueryModel, new()
        {
            var snapshotTypeName = typeof(TProjector).Name;
            var snapshot         = _snapshotPersister.Load(id.AsString(), to, snapshotTypeName);
            var projector        = _factory.Create <TViewModel>(typeof(TProjector), id);

            Int32      startsFromEvent = 0;
            IMementoEx memento         = snapshot == null ? null : (IMementoEx)snapshot.Payload;

            if (memento != null)
            {
                if (!projector.ValidateMemento(memento))
                {
                    _snapshotPersister.Clear(id.AsString(), memento.Version, snapshotTypeName);
                }
                else
                {
                    projector.Restore(memento);
                    startsFromEvent = snapshot.StreamRevision;
                }
            }

            using (var events = _eventStore.OpenStream(projector.BucketId, id.AsString(), startsFromEvent, to))
            {
                Int32 eventCount = 0;
                foreach (var evt in events.CommittedEvents)
                {
                    projector.ApplyEvent((DomainEvent)evt.Body);
                    eventCount++;
                }

                if (projector.ShouldSnapshot(eventCount))
                {
                    memento  = projector.GetSnapshot();
                    snapshot = new Snapshot(id.AsString(), events.StreamRevision, memento);
                    _snapshotPersister.Persist(snapshot, snapshotTypeName);
                }
            }

            return((TProjector)projector);
        }
        public void Snapshot(IAggregateEx aggregate, String bucket, Int32 numberOfEventsSaved)
        {
            if (SnapshotsSettings.HasOptedOut(aggregate.GetType()))
            {
                return;
            }

            var memento  = aggregate.GetSnapshot();
            var snapshot = new Snapshot(bucket, aggregate.Id.AsString(), aggregate.Version, memento);

            if (_cacheEnabled)
            {
                _cache.Set(aggregate.Id.AsString(), snapshot, _standardCachePolicy);
            }

            if (_snapshotPersistenceStrategy.ShouldSnapshot(aggregate, numberOfEventsSaved))
            {
                _persister.Persist(snapshot, aggregate.GetType().FullName);
            }
        }