-
Notifications
You must be signed in to change notification settings - Fork 0
Auto Subscriber
From v0.7.1.30 EasyNetQ comes with a simple AutoSubscriber
. You can use it to easily scan a specific assembly for classes that implements the interface IConsume<T>
, and then let the auto subscriber subscribe these consumers to your bus. You can of course let your consumers handle multiple messages. Lets have a look at some samples.
Lets define a simple consumer, handling two messages: MessageA
and MessageB
.
public class MyConsumer : IConsume<MessageA>, IConsume<MessageB>
{
public void Consume(MessageA message) { }
public void Consume(MessageB message) { }
}
First create a new instance of AutoSubscriber, passing your IBus instance and a subscriptionId prefix to the constructor. The subscriptionId prefix is prefixed to all auto-generated subscriptionIds, but not to custom subscriptionIds (see below).
To register this, and all other consumers in the same Assembly, we just need to pass the assembly that contains your consumers to: AutoSubscriber.Subscribe(assembly)
. Note! This is something you only should do ONCE, preferably on application start up.
var subscriber = new AutoSubscriber(bus, "my_applications_subscriptionId_prefix");
subscriber.Subscribe(Assembly.GetExecutingAssembly());
By default the AutoSubscriber
will generate a unique SubscriptionId
. If you would like it to be fixed, you can decorate the Consume
method with the ConsumerAttribute
. Why you would make it fixed, is something you can read up about here.
Lets say, the consumer above should have a fixed SubscriptionId
for the consumer method of MessageB
. Just decorated it and define a value for SubscriptionId
.
[Consumer(SubscriptionId = "MyExplicitId")]
public void Consume(MessageB message) { }
You could of course also take control of the actual SubscriptionId
generation. Just replace the AutoSubscriber.GenerateSubscriptionId : Func<ConsumerInfo, string>
.
var subscriber = new AutoSubscriber(bus)
{
CreateConsumer = t => objectResolver.Resolve(t),
GenerateSubscriptionId = c => AppDomain.CurrentDomain.FriendlyName + c.ConcreteType.Name
};
subscriber.Subscribe(Assembly.GetExecutingAssembly());
Note! Just a sample implementation. Ensure you have read and understood the importance of the SubscriptionId
value.
##Using an IoC container with AutoSubscriber
AutoSubscriber has a property, MessageDispatcher, which allows you to plug in your own message dispatching code. This allows you to resolve your consumers from an IoC container or do other custom dispatch time tasks.
Let's write a custom IMessageDispatcher to resolve consumers from the Windsor IoC container
public class WindsorMessageDispatcher : IMessageDispatcher
{
private readonly IWindsorContainer container;
public WindsorMessageDispatcher(IWindsorContainer container)
{
this.container = container;
}
public void Dispatch<TMessage, TConsumer>(TMessage message) where TMessage : class where TConsumer : IConsume<TMessage>
{
var consumer = (IConsume<TMessage>)container.Resolve<TConsumer>();
try
{
consumer.Consume(message);
}
finally
{
container.Release(consumer);
}
}
}
Now we need to register our consumer with our IoC container:
var container = new WindsorContainer();
container.Register(
Component.For<MyConsumer>().ImplementedBy<MyConsumer>()
);
Next setup the AutoSubscriber with our custom IMessageDispatcher:
var bus = RabbitHutch.CreateBus("host=localhost");
var autoSubscriber = new AutoSubscriber(bus, "My_subscription_id_prefix")
{
MessageDispatcher = new WindsorMessageDispatcher(container)
};
autoSubscriber.Subscribe(GetType().Assembly);
Now each time a message arrives a new instance of our consumer will be resolved from our container.