ProSol.Messaging/src/Publishers/PipelineMessagePublisher.cs

43 lines
1.4 KiB
C#

namespace ProSol.Messaging;
/// <summary>
/// Collects a subscribers and publishes a messages to them.
/// Provides a pipeline mechanics, so a subscriber is able to stop message processing.
/// </summary>
/// <typeparam name="TMessage"> Type of message. </typeparam>
public class PipelineMessagePublisher<TMessage>
: IPublisher<TMessage>
{
private readonly HashSet<IPipelineSubscriber<TMessage>> subscribers = [];
/// <summary>
/// Subscribes a subscriber.
/// </summary>
/// <param name="subscriber"> An implementation of <see cref="IPipelineSubscriber"/> interface. </param>
/// <returns> Unsubscriber. </returns>
public IDisposable Subscribe(IPipelineSubscriber<TMessage> subscriber)
{
subscribers.Add(subscriber);
return new Unsubscriber<TMessage>(subscribers, subscriber);
}
/// <summary>
/// Pushes the message to subscribers.
/// </summary>
/// <param name="message"> A message to push to specific <see cref="IPipelineSubscriber"/>. </param>
public void Publish(TMessage message)
=> this.Publish(message, [.. subscribers]);
/// <summary>
/// Pushes the `complete` message, so the subscribers can finalize the subscription.
/// </summary>
public void Complete()
{
foreach (var item in subscribers)
{
item.OnCompleted();
}
subscribers.Clear();
}
}