private async Task HandleFailedProjectionAsync(TEventItem eventItem, Exception exception)
    {
        _logger.LogWarning("Writing dead lettered event item for event {EventId} with name {EventName}",
                           eventItem.Id,
                           eventItem.EventName);

        DeadLetteredEventItem <TEventItem> deadLetteredItem = new(
            eventItem,
            _processorOptions.ProcessorName,
            _processorOptions.InstanceName,
            typeof(TProjectionKey).Name,
            new ExceptionDetails(
                exception.GetType().Name,
                exception.ToString()));

        try
        {
            await _repository.CreateAsync(deadLetteredItem);
        }
        catch (Exception e)
        {
            _logger.LogError(e, "Failed to save dead lettered event item for event {EventId} with name {EventName}",
                             eventItem.Id,
                             eventItem.EventName);
            throw;
        }
    }
    public async ValueTask ProjectAsync(
        TodoListEventItem eventItem,
        CancellationToken cancellationToken = default)
    {
        if (eventItem.DomainEvent is TodoListCreated created)
        {
            _logger.LogInformation("TodoListCreated being processed with ID {TodoId} and name {TodoName}",
                                   eventItem.Id,
                                   created.Name);

            await _repository.CreateAsync(new TodoListItem(created.Name), cancellationToken);
        }
    }