I am working on a modular ASP.NET MVC application, one of the problems is communication among modules. At the beginning, with just 3 - 4 modules, it might seem possible to call methods among modules directly. As the system grows, number of modules increases and dependencies among modules become more complex, such solution become impractical.
I didn't need anything fancy, just a simple publisher/subscriber pattern implementation for the single application, so I decided to write my own 'library'.
I didn't need anything fancy, just a simple publisher/subscriber pattern implementation for the single application, so I decided to write my own 'library'.
![]() |
| Publisher - subscriber pattern |
Implementation
The core of the implementation is the MessageBus class. A publisher obtains an instance of the MessageBus (from IoC container), sends a message and the MessageBus distributes the message to appropriate subscribers.
Subscribers need to implement the IMessageSubscriber<TMessage>
interface, so they can process messages of the desired type.
public interface IMessageSubscriber<TMessage> where TMessage : IMessage {
void Handle(TMessage msg);
}
The actual implementation of MessageBus is pretty simple, the difficult part - managing references to subscribers is done by an IoC container (encapsulated in IDependencyResolver). An IoC container is usually already in place in MVC applications, so why reinvent a wheel ...
public class MessageBus : IMessageBus {
IDependencyResolver _resolver;
public MessageBus(IDependencyResolver resolver) {
_resolver = resolver;
}
public void Send<TMessage>(TMessage message) where TMessage : IMessage {
var subscribers = _resolver.Resolve<IMessageSubscriber<TMessage>>();
foreach (var subscriber in subscribers) {
subscriber.Handle(message);
}
}
}
The final piece of the implementation is registering all necessary classes in the IoC container - in this case I used Autofac.
ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<MessageBus>().As<IMessageBus>(); builder.RegisterType<DEPENDENCY_RESOLVER>().As<IDependencyResolver>(); builder.RegisterType<SUBSCRIBER>().As<IMessageSubscriber<MESSAGE>>();
To send a message publisher needs to obtain an instance of the MessageBus from the IoC container and than send the message.
bus = container.Resolve<IMessageBus>();
SampleMessage msg = new SampleMessage() { Content = message };
bus.Send<SampleMessage>(msg);
And that's it - a simple message bus, that fulfill my requirements in about 20 lines of code. You can download the source code of the MessageBus with a MVC demo project from GitHub

No comments:
Post a Comment