/// <summary>
        /// Adds an <see cref="ExactlyOnceMiddleware{T}"/> to the current pipeline.
        /// </summary>
        /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
        /// <param name="lockKey">A unique key to identify this lock, e.g. the name of the handler.</param>
        /// <param name="lockDuration">The length of time to lock messages while handling them.</param>
        /// <typeparam name="TMessage">The type of the message that should be locked.</typeparam>
        /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
        public static HandlerMiddlewareBuilder UseExactlyOnce <TMessage>(
            this HandlerMiddlewareBuilder builder,
            string lockKey,
            TimeSpan?lockDuration = null)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (string.IsNullOrEmpty(lockKey))
            {
                throw new ArgumentException("Parameter cannot be null or empty.", nameof(lockKey));
            }

            HandleMessageMiddleware CreateMiddleware()
            {
                var messageLock = builder.ServiceResolver.ResolveService <IMessageLockAsync>();
                var logger      = builder.ServiceResolver.ResolveService <ILogger <ExactlyOnceMiddleware <TMessage> > >();

                return(new ExactlyOnceMiddleware <TMessage>(messageLock,
                                                            lockDuration ?? TimeSpan.MaxValue,
                                                            lockKey,
                                                            logger));
            }

            builder.Use(CreateMiddleware);

            return(builder);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Adds a <see cref="StopwatchMiddleware"/> to the current pipeline.
        /// </summary>
        /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
        /// <param name="handlerType">The type of the handler that results should be reported against.</param>
        /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="builder"/> is <see langword="null"/>.
        /// </exception>
        public static HandlerMiddlewareBuilder UseStopwatch(
            this HandlerMiddlewareBuilder builder,
            Type handlerType)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            IMessageMonitor monitor = builder.ServiceResolver.ResolveService <IMessageMonitor>();

            return(builder.Use(new StopwatchMiddleware(monitor, handlerType)));
        }
        /// <summary>
        /// Adds a <see cref="HandlerInvocationMiddleware{T}"/> to the current pipeline.
        /// </summary>
        /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
        /// <param name="handler">A factory that creates <see cref="IHandlerAsync{T}"/> instances from
        /// a <see cref="HandlerResolutionContext"/>.</param>
        /// <typeparam name="TMessage">The type of the message that should be handled</typeparam>
        /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="builder"/> or <paramref name="handler"/> is <see langword="null"/>.
        /// </exception>
        public static HandlerMiddlewareBuilder UseHandler <TMessage>(
            this HandlerMiddlewareBuilder builder,
            Func <HandlerResolutionContext, IHandlerAsync <TMessage> > handler) where TMessage : Message
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            return(builder.Use(new HandlerInvocationMiddleware <TMessage>(handler)));
        }
        /// <summary>
        /// <para>
        /// Applies a set of default middlewares in order. Adding other middlewares before this will add them
        /// to the top of the stack, and are run first and last.
        /// Adding other middleware after this will add them to the bottom of the stack, just before the
        /// handler itself is invoked.
        /// </para>
        /// The middlewares this adds are, in order:
        /// <list type="bullet">
        /// <item>MessageContextAccessorMiddleware</item>
        /// <item>BackoffMiddleware (only if an <see cref="IMessageBackoffStrategy"/> is available)</item>
        /// <item>ErrorHandlerMiddleware</item>
        /// <item>LoggingMiddleware</item>
        /// <item>StopwatchMiddleware</item>
        /// <item>SqsPostProcessorMiddleware</item>
        /// <item>HandlerInvocationMiddleware`1</item>
        /// </list>
        /// </summary>
        /// <param name="builder">The <see cref="HandlerMiddlewareBuilder"/> builder to add these defaults to.</param>
        /// <param name="handlerType">The type of the handler that will handle messages for this middleware pipeline.
        /// This is used when recording handler execution time with the StopwatchMiddleware.</param>
        /// <typeparam name="TMessage">The type of the message that this middleware pipeline handles.</typeparam>
        /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
        public static HandlerMiddlewareBuilder UseDefaults <TMessage>(
            this HandlerMiddlewareBuilder builder,
            Type handlerType)
            where TMessage : Message
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (handlerType == null)
            {
                throw new ArgumentNullException(nameof(handlerType), "HandlerType is used here to");
            }

            builder.UseMessageContextAccessor();
            builder.UseErrorHandler();
            builder.Use <LoggingMiddleware>();
            builder.UseStopwatch(handlerType);
            builder.Use <SqsPostProcessorMiddleware>();
            builder.UseHandler <TMessage>();

            return(builder);
        }