public async ValueTask OnMessageCreate(IDiscordMessage message)
        {
            var @event = new MessageReceivedEvent(message);

            await _eventManager.CallAsync(@event);

            if (@event.IsCancelled || string.IsNullOrEmpty(message.Content))
            {
                return;
            }

            var scope           = _provider.CreateScope();
            var features        = new FeatureCollection();
            var responseFeature = new MessageResponseFeature();

            features.Set <IServiceProvidersFeature>(new ServiceProvidersFeature(scope.ServiceProvider));
            features.Set <IUserFeature>(new UserFeature(message.Author));
            features.Set <IMessageResponseFeature>(responseFeature);
            features.Set <IMessageRequestFeature>(new MessageRequestFeature
            {
                GuildId   = message.GuildId,
                ChannelId = message.ChannelId,
                MessageId = message.Id,
                Message   = message.Content
            });

            var context = _messageContextFactory.Create(features);

            try
            {
                CultureInfo.CurrentCulture = _localizer.DefaultCulture;

                _contextAccessor.Context = context;

                await _application(context);

                await _contextDispatcher.DispatchAsync(context);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An exception occured while processing the message '{Content}' from {User}.", message.Content, message.Author.Username);

                if (_debugOptions.ThrowOnMessageException)
                {
                    throw;
                }
            }
            finally
            {
                scope.Dispose();
                _messageContextFactory.Dispose(context);
            }
        }
        public async Task DispatchAsync(Func <MessageContext, Task> func, FeatureCollection features = null)
        {
            var context = _factory.Create(features ?? new FeatureCollection());

            try
            {
                await func(context);
                await DispatchAsync(context);
            }
            finally
            {
                _factory.Dispose(context);
            }
        }