private Func <EventStoreCatchUpSubscription, ResolvedEvent, Task> EventAppeared(
            ProjectionHandler projection,
            string projectionName
            ) => async(_, e) =>
        {
            if (e.OriginalEvent.EventType.StartsWith("$"))
            {
                return;
            }

            var @event = this._eventDeserializer.Deserialize(Type.GetType(e.Event.EventType), Encoding.UTF8.GetString(e.Event.Data));

            @event.ThrowsIfNull(new ArgumentNullException(nameof(@event)));

            await projection.Handle(@event);

            await _checkpointStore.SetLastCheckpoint(projectionName, e.OriginalPosition);

            var metadata = this._eventDeserializer.Deserialize <EventMetadata>(Encoding.UTF8.GetString(e.Event.Metadata));

            ISnapshotter snapshotStore = _snapshotters.FirstOrDefault(
                x => x.ShouldTakeSnapshot(Type.GetType(metadata.AggregateAssemblyQualifiedName), e) && !metadata.IsSnapshot);

            if (snapshotStore != null)
            {
                await snapshotStore.TakeSnapshotAsync(e.OriginalStreamId);
            }
        };
        private Action <EventStoreCatchUpSubscription, ResolvedEvent> EventAppeared(
            Projector <TConnection> projection,
            string projectionName
            ) => async(_, e) =>
        {
            // check system event
            if (e.OriginalEvent.EventType.StartsWith("$"))
            {
                return;
            }

            // get the configured clr type name for deserializing the event
            //var eventType = _typeMapper.GetType(e.Event.EventType);

            // try to execute the projection
            await projection.ProjectAsync(_getConnection(), ComposeEnvelope(_serializer.Deserialize(e), e.OriginalPosition.Value.CommitPosition));

            Log.Debug("{projection} projected {eventType}({eventId})", projectionName, e.Event.EventType, e.Event.EventId);

            //**** Storing Checkpoint ****/
            //1.Way
            // await projection.ProjectAsync(_getConnection(), new SetProjectionPosition(e.OriginalPosition));
            //2.Way
            await _checkpointStore.SetLastCheckpoint(projectionName, e.OriginalPosition);

            var          metadata    = JsonConvert.DeserializeObject <EventMetadata>(Encoding.UTF8.GetString(e.Event.Metadata));
            ISnapshotter snapshotter = _snapshotters.FirstOrDefault(
                x => x.ShouldTakeSnapshot(Type.GetType(metadata.AggregateAssemblyQualifiedName), e) && !metadata.IsSnapshot);

            if (snapshotter != null)
            {
                await snapshotter.Take(e.OriginalStreamId);

                Log.Debug("Snapshot was taken for {aggregate} on event{eventType}{eventId} at number {eventNumber}",
                          metadata.AggregateType, e.Event.EventType, e.Event.EventId, e.Event.EventNumber);
            }
        };