For my series of articles on modular monolith architecture I needed a request/reply message broker that could pass data between isolated sections of my modular monolith.
At first I couldn't find a message broker that worked like a method call (most message broker use the publish/listen approach), so I build a simple request/reply message broker, but I now have found a possible request/reply broker in RabbitMQ (but it comes with a lot of other features I don't need).
RabbitMQ has a remote procedure call feature that uses a queue, but this page shows how to turn off the queue.
MIT license.
My simple message broker can be used without dependency injection (DI) as shown below. This isn't the normal use but is a simple example to understand waht is going on.
var broker = new MessageBroker(null);
//You register a communication link called "link-name"
//Which will receive a string from the asker and returns class
broker.RegisterGetter("link-name",
fromAsker => new ClassToSend(fromAsker));
//To ask the getter on the same communication link name
//for a class, sending an optional string
var result = broker.AskFor<ClassToSend>("link-name", "hello");
In real applications you would use DI, with the message broker register as a singleton (that's important) with your DI provider. Then you should register all your getter services using the RegisterGetterService
method. This allows your Getter class to use DI to get other services, such as access to the database.
When the AskFor
is called the broker will create a scoped instance of your class to get the data and then dispose of it.
The code below shows this in action.
var broker = //You get the singleton message broker via DI
//You register a getter service with the interface IGetService
broker.RegisterGetterService<ClassToSend, IGetService>("Test");
//When you ask for the get data the broker will create a scoped instance to get the data
var result = broker.AskFor<ClassToSend>("Test", "hello").Data;
See the TestMessageBrokerWithDi
unit tests for more information.
- request/reply for the same class
- request/reply for differnet classes by using json serialize/deserialize to map the get type to the ask type.
- Add register interface and create an instance (via DI) of the Getter when
AskFor
method is called.
- Add Async support