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); }
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); }
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); }
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<TmessageType,CancellationToken,Task>"/>. /// </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); }
/// <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); }
/// <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<TmessageType,CancellationToken,Task>"/>. /// </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); }
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); } }
/// <summary> /// Builds the message handler chain /// </summary> /// <param name="services"> /// The setup notification services. /// </param> /// <returns> /// The <see cref="Func<TmessageType,CancellationToken,Task>" />. /// </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); }
/// <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); }
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); }