/// <summary>
        /// Adds a combined consumer/future, where the future handles the requests and the consumer is only known to the future.
        /// This is a shortcut method,
        /// </summary>
        /// <param name="configurator"></param>
        /// <param name="configure"></param>
        /// <typeparam name="TFuture">The consumer type</typeparam>
        /// <typeparam name="TConsumer"></typeparam>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="TResponse"></typeparam>
        public static IFutureRegistrationConfigurator <TFuture> AddFutureRequestConsumer <TFuture, TConsumer, TRequest, TResponse>(
            this IRegistrationConfigurator configurator, Action <IConsumerConfigurator <TConsumer> > configure = null)
            where TFuture : Future <TRequest, TResponse>
            where TRequest : class
            where TResponse : class
            where TConsumer : class, IConsumer <TRequest>
        {
            configurator.AddConsumer <TConsumer, FutureRequestConsumerDefinition <TConsumer, TRequest> >(configure);

            return(configurator.AddFuture <TFuture, RequestConsumerFutureDefinition <TFuture, TConsumer, TRequest, TResponse> >());
        }
        /// <summary>
        /// Adds the specified consumer types which match the given filter
        /// </summary>
        /// <param name="configurator"></param>
        /// <param name="filter"></param>
        /// <param name="types">The consumer types to add</param>
        public static void AddFutures(this IRegistrationConfigurator configurator, Func <Type, bool> filter, params Type[] types)
        {
            filter ??= t => true;

            IEnumerable <Type> consumerTypes           = types.Where(x => x.HasInterface(typeof(SagaStateMachine <FutureState>)));
            IEnumerable <Type> consumerDefinitionTypes = types.Where(x => x.HasInterface(typeof(IFutureDefinition <>)));

            var futures = from c in consumerTypes
                          join d in consumerDefinitionTypes on c equals d.GetClosingArgument(typeof(IFutureDefinition <>)) into dc
                          from d in dc.DefaultIfEmpty()
                              where filter(c)
                          select new
            {
                FutureType     = c,
                DefinitionType = d
            };

            foreach (var future in futures)
            {
                configurator.AddFuture(future.FutureType, future.DefinitionType);
            }
        }
 /// <summary>
 /// Adds the consumer, allowing configuration when it is configured on an endpoint
 /// </summary>
 /// <param name="configurator"></param>
 /// <typeparam name="T">The consumer type</typeparam>
 /// <typeparam name="TDefinition">The consumer definition type</typeparam>
 public static IFutureRegistrationConfigurator <T> AddFuture <T, TDefinition>(this IRegistrationConfigurator configurator)
     where T : MassTransitStateMachine <FutureState>
     where TDefinition : class, IFutureDefinition <T>
 {
     return(configurator.AddFuture <T>(typeof(TDefinition)));
 }