Пример #1
0
        public void FirstDecorator_Tests()
        {
            var count = 0;

            var notification = new TestChainBuilderNotifier();
            var services     = new ChainBuilderSetupServices(notification);

            var chain = new ChainBuilder <int>().First(m => m == 2).Handler(m => count++).BuildFunc(services);

            // The notification is disposed when the Take handler has processed 2 messages, trying to process the 3rd
            Assert.False(notification.IsDisposed);
            Assert.Equal(0, count);

            chain(1, CancellationToken.None);

            Assert.Equal(0, count);

            chain(2, CancellationToken.None);

            Assert.Equal(1, count);

            chain(3, CancellationToken.None);

            Assert.True(notification.IsDisposed);

            chain(4, CancellationToken.None);

            // Skip the rest - still 2
            Assert.Equal(1, count);
        }
Пример #2
0
        public void SelectManyDecorator_Test()
        {
            var count = 0;

            var notification = new TestChainBuilderNotifier();
            var services     = new ChainBuilderSetupServices(notification);
            var builder      = new ChainBuilder <OuterMessage>();

            builder.SelectMany(m => m.Messages).Skip(2).Take(2).Handler(m => count++);
            var chain = builder.BuildFunc(services);

            Assert.False(notification.IsDisposed);
            Assert.Equal(0, count);

            chain(
                new OuterMessage
            {
                Messages = new[] { 1, 2, 3 }
            },
                CancellationToken.None);

            Assert.False(notification.IsDisposed);
            Assert.Equal(1, count);

            chain(
                new OuterMessage
            {
                Messages = new[] { 4, 5, 6 }
            },
                CancellationToken.None);

            Assert.Equal(2, count);
            Assert.True(notification.IsDisposed);
        }
Пример #3
0
        public void TakeWhileAsyncDecorator_Tests()
        {
            var count = 0;

            var notification = new TestChainBuilderNotifier();
            var services     = new ChainBuilderSetupServices(notification);

            var chain = new ChainBuilder <int>().TakeWhile(m => Task.FromResult(m <= 2)).Handler(m => count++).BuildFunc(services);

            // The notification is disposed when the Take handler has processed 2 messages, trying to process the 3rd
            Assert.False(notification.IsDisposed);
            Assert.Equal(0, count);

            chain(1, CancellationToken.None);
            chain(2, CancellationToken.None);

            // 2 should be skipped taken
            Assert.Equal(2, count);

            chain(3, CancellationToken.None);

            Assert.True(notification.IsDisposed);

            chain(4, CancellationToken.None);

            // Skip the rest - still 2
            Assert.Equal(2, count);
        }
Пример #4
0
 public FirstAsyncDecorator(
     Func <TMessageType, CancellationToken, Task> handlerFunc,
     Func <TMessageType, CancellationToken, Task <bool> > asyncPredicate,
     ChainBuilderSetupServices subscriptionServices)
 {
     this.handlerFunc    = handlerFunc;
     this.asyncPredicate = asyncPredicate;
     subscriptionServices.BuilderNotifier.AddNotification(this.ChainBuilt);
 }
        public void ChainBuilt(IChain chain)
        {
            var subscriptionNotification = new ChainBuilderNotifier();
            var services  = new ChainBuilderSetupServices(subscriptionNotification);
            var chainFunc = this.newchainBuilder.BuildFunc(services);

            this.newChain = new Chain <TNewMessageType>(chainFunc, chain.Dispose);
            subscriptionNotification.Notify(this.newChain);
        }
        /// <summary>
        /// Builds the message handler chain
        /// </summary>
        /// <typeparam name="TMessageType">The message type
        /// </typeparam>
        /// <param name="chainBuilder">
        /// The message Handler chain Builder.
        /// </param>
        /// <returns>
        /// The <see cref="Func&lt;TmessageType,CancellationToken,Task&gt;"/>.
        /// </returns>
        public static Func <TMessageType, CancellationToken, Task> BuildFunc <TMessageType>(this IChainBuilder <TMessageType> chainBuilder)
        {
            var subscriptionNotification = new ChainBuilderNotifier();
            var services = new ChainBuilderSetupServices(subscriptionNotification);
            var func     = chainBuilder.BuildFunc(services);

            var chain = new Chain <TMessageType>(func, ActionHelpers.NoAction);

            subscriptionNotification.Notify(chain);

            return(func);
        }
Пример #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ParallelMessageHandlerChainPublisher{TMessageType}"/> class.
        /// </summary>
        /// <param name="ChainBuilder">
        /// The message handler chain builder
        /// </param>
        public ParallelMessageHandlerChainPublisher(ChainBuilder <MessageAndHandler <TMessageType> > ChainBuilder)
        {
            ChainBuilder.Handler(this.PublishAsync);

            var subscriptionNotification = new ChainBuilderNotifier();
            var services = new ChainBuilderSetupServices(subscriptionNotification);

            this.publisher = ChainBuilder.BuildFunc(services);

            var chain = new Chain <MessageAndHandler <TMessageType> >(this.publisher);

            subscriptionNotification.Notify(chain);
        }
Пример #8
0
        /// <summary>
        /// Builds a message handler chain from the decorators and the handler added
        /// </summary>
        /// <param name="disposeAction">
        /// The action to call when the chain dispose method is called.
        /// </param>
        /// <returns>
        /// The <see cref="Func&lt;TmessageType,CancellationToken,Task&gt;"/>.
        /// </returns>
        public IChain <TMessageType> BuildChain(Action disposeAction = null)
        {
            var subscriptionNotification = new ChainBuilderNotifier();
            var services = new ChainBuilderSetupServices(subscriptionNotification);

            var func = this.BuildFunc(services);

            disposeAction = disposeAction ?? ActionHelpers.NoAction;

            var chain = new Chain <TMessageType>(func, disposeAction);

            subscriptionNotification.Notify(chain);

            return(chain);
        }
Пример #9
0
        public void ChainBuilt(IChain chain)
        {
            this.parentChain = chain;

            foreach (var branch in this.branches)
            {
                var builder = new ChainBuilder <TMessageType>();
                branch(builder);

                var notifier  = new ChainBuilderNotifier();
                var services  = new ChainBuilderSetupServices(notifier);
                var chainFunc = builder.BuildFunc(services);

                this.handlers.Add(chainFunc);

                var newChain = new Chain <TMessageType>(chainFunc, () => this.Unsubscribe(chainFunc));
                notifier.Notify(newChain);
            }
        }
Пример #10
0
        /// <summary>
        ///     Builds the message handler chain
        /// </summary>
        /// <param name="services">
        ///     The setup notification services.
        /// </param>
        /// <returns>
        ///     The <see cref="Func&lt;TmessageType,CancellationToken,Task&gt;" />.
        /// </returns>
        public Func <TMessageType, CancellationToken, Task> BuildFunc(ChainBuilderSetupServices services)
        {
            if (this.createHandlerFunc == null)
            {
                throw new ChainHasNoMessageHandlerException("The message handler chain does not have a message handler");
            }

            var handlerFunc = this.createHandlerFunc(services);

            if (this.decoratorSetupFuncs == null || this.decoratorSetupFuncs.Count == 0)
            {
                return(handlerFunc);
            }

#pragma warning disable CC0031 // Check for null before calling a delegate
            return(this.decoratorSetupFuncs.Aggregate(handlerFunc, (current, handlerSetupFunc) => handlerSetupFunc(current, services)));

#pragma warning restore CC0031 // Check for null before calling a delegate
        }
        private static BusOptions <TMessageType> UseSubscriptionChain <TMessageType>(
            BusOptions <TMessageType> options,
            ChainBuilder <MessageAndHandler <TMessageType> > builder)
        {
            if (builder.HasHandler == false)
            {
                builder.Handler(PublishToSubscription.PublishAsync);
            }

            var subscriptionNotification = new ChainBuilderNotifier();
            var services  = new ChainBuilderSetupServices(subscriptionNotification);
            var chainFunc = builder.BuildFunc(services);
            var newChain  = new Chain <MessageAndHandler <TMessageType> >(chainFunc);

            subscriptionNotification.Notify(newChain);

            options.UseCustomPublisher(new ParallelMessageHandlerChainPublisher <TMessageType>(chainFunc));
            return(options);
        }
Пример #12
0
        /// <summary>
        ///     Create a message handler chain to set up a subscription
        /// </summary>
        /// <typeparam name="TMessageType">The message type</typeparam>
        /// <param name="subscriptions">The subscriptions interface</param>
        /// <param name="setupAction">The method called to configure the message handler chain for the new subscription</param>
        /// <returns>The new message handler chain</returns>
        public static IChain <TMessageType> Subscribe <TMessageType>(
            this IMessageBusSubscriptions <TMessageType> subscriptions,
            Action <IChainBuilder <TMessageType> > setupAction)
        {
            var builder = new ChainBuilder <TMessageType>();

            setupAction(builder);

            var subscriptionNotification = new ChainBuilderNotifier();
            var services  = new ChainBuilderSetupServices(subscriptionNotification);
            var chainFunc = builder.BuildFunc(services);

            var subscription = subscriptions.Subscribe(chainFunc);

            var chain = new Chain <TMessageType>(chainFunc, subscription.Dispose);

            subscriptionNotification.Notify(chain);

            return(chain);
        }
Пример #13
0
        public void SkipWhileDecorator_Tests()
        {
            var count = 0;

            var notification = new TestChainBuilderNotifier();
            var services     = new ChainBuilderSetupServices(notification);

            var chain = new ChainBuilder <int>().SkipWhile(m => m <= 2).Handler(m => count++).BuildFunc(services);

            // The notification is disposed when the Take handler has processed 2 messages, trying to process the 3rd
            Assert.Equal(0, count);

            chain(1, CancellationToken.None);
            chain(2, CancellationToken.None);

            // 0 should be taken
            Assert.Equal(0, count);

            chain(3, CancellationToken.None);
            chain(4, CancellationToken.None);

            // take the rest - still 2
            Assert.Equal(2, count);
        }