Some of you may remember Postal.NET from my previous posts (here, here and here). In a nutshell, it is a framework I built for writing decoupled applications in .NET, in a publish-subscribe way. It is available as open source in GitHub (do have a look at the README file) and available in Nuget.
I recently added request-response synchronous support. This is so that two parties, without knowing exactly who they are, can engage in a direct conversation. Other enterprise buses support this feature as well.
So, with that in mind, let’s recap all of the messaging patterns we have in Postal.NET. Remember that at least you need to grab the Postal.NET Nuget package.
OK, this is easy: someone subscribes to a channel-topic pair and someone else publishes a message to it, either synchronously or asynchronously:
var subscription = Postal.Box.Subscribe("some channel", "some topic", (env) => ProcessMessage(env));
Postal.Box.Publish("some channel", "some topic", someMessage);
await Postal.Box.PublishAsync("some channel", "some topic", someMessage);
It is also possible to subscribe to all messages and equally to broadcast to all channels and topics:
//subscribe to all channels and topics
var broadcastSubscription = Postal.Box.Subscribe("*", "*", (env) => ProcessAllMessages(env));
//broadcast to all channels and topics
await Postal.Box.PublishAsync("*", "*", shutdownMessage);
Finally, it is possible to conditionally process a message:
var filteredSubscription = Postal.Box.Subscribe("some channel", "some topic", (env) => ProcessMessage(env), (env) => env.Data is string);
Publish-Subscribe to Multiple Channels
Another option is to subscribe to multiple channel/topic pairs at the same time:
var combinedSubscription = Postal.Box.SubscribeMultiple("some channel", "a topic, another topic", (env) => ProcessMessage(env));
Here, an event will be raised if a message is published to any of the given topics, separated by commas.
Likewise, it is also possible to publish at the same time to several channels:
await Postal.Box.PublishAsync("a channel", "a topic, another topic", someMessage);
When the subscription is cancelled, it will cancel all channel/topic pairs at the same time.
Handle a Single Event
You can subscribe to an event only once and terminate the subscription as soon as you receive it, no need (or possible) to cancel it:
Postal.Box.Once("a channel", "a topic", (env) => ProcessMessage(env));
Yet another option is to use composition: do something only after this and that event has occurred. You need to install first the PostalWhen.NET package.
var composedSubscription = Postal
.When("a channel", "a topic")
.And("a channel", "another topic", (env) => ShouldProcess(env))
.Subscribe(env => ProcessSaga(env));
Postal.NET plugs in nicely with Reactive Extensions, including all of its goodies, like buffering. Get PostalRX.NET:
var observable = Postal.Box.Observe("a channel", "a topic");
//groups 5 messages
var bufferedSubscription = observable
//msgs is a collection of 5 envelopes
.Subscribe((msgs) => ProcessBufferedMessage(msgs), (ex) => ProcessException(ex), () => ProcessTermination());
The last pattern added was request-response. With it, you can reply synchronously to the requestor, each without knowing about the other. The code for this lives in Nuget as PostalRequestResponse.NET:
var subscription = Postal.Box.Subscribe("a channel", "a topic", (env) =>
//check if it is a request-response message
if (env.IsRequestResponse() == true)
//extract the contents from it
var someMessage = env.Unwrap<SomeMessage>();
//Gets the results from GetResponse synchronously
var response = Postal.Box.Request("a channel", "a topic", someMessage);
You can see that Postal.NET offers some interesting patterns which hopefully cover most use cases. If you want to know more, do check out GitHub or drop me a note!