I am using Unity App Block as my IOC container for my service layer of a WCF project. This works quite well using the Unity.WCF library to plug it into each WCF service.
I recently introduced RabbitMQ into my service layer and I am currently using the "using" blocks to connect and add to the queue. I dont like this though and am looking to use the HierachicalLifetimeManager
to create and destroy my connection to RabbitMQ as I need them? Does this sound correct?
I'm looking for a sample of this, or atleast some guidance on the best approach? (e.g. Should I encapsulate the connection and inject into each service as needed? How would I encapsulate RabbitMQ consumer etc?)
I would advise registering the IConnection
as a singleton.
To register the IConnection
as a singleton in Unity you would use a ContainerControlledLifetimeManager
, e.g.
var connectionFactory = new ConnectionFactory
{
// Configure the connection factory
};
unityContainer.RegisterInstance(connectionFactory);
unityContainer.RegisterType<IConnection, AutorecoveringConnection>(new ContainerControlledLifetimeManager(),
new InjectionMethod("init"));
The AutorecoveringConnection
instance, once resolved for the first time will stay alive until the owning UnityContainer
is disposed.
Because we have registered the ConnectionFactory
with Unity
, this will automatically be injected into the constructor of AutorecoveringConnection
.
The InjectionMethod
ensures that the first time the AutorecoveringConnection
is resolved, the init
method is invoked.
As for your question about whether you should abstract away RabbitMQ from your services, my answer would be yes, however I would not simply create an IMessageQueue
abstraction. Think about what purpose you are using your message queue for, is it to push statuses? If so, have an IStatusNotifier
interface with a concrete implementation for RabbitMQ. If it's to fetch updates, have an IUpdateSource
interface with a concrete implementation for RabbitMQ. You can see where I am going with this.
If you create an abstraction for a Message Queue, you are limiting yourself to features only available across all Message Queue implementations. By having a different implementation of IStatusNotifier
for different Message Queue implementations, you are able to take advantage of features which are unique to different technologies while also remaining flexible in case completely different technologies are employed in future (e.g. Writing to a SQL database or outputting to a console).
With RabbitMQ you want your IConnection to be re-used all the time, you don't want it in a "using" block. Here is my IOC binding using Ninject, note the InSingletonScope, this is what you want.
Bind<IConnection>()
.ToMethod(ctx =>
{
var factory = new ConnectionFactory
{
Uri = ConfigurationManager.ConnectionStrings["RabbitMQ"].ConnectionString,
RequestedHeartbeat = 15
//every N seconds the server will send a heartbeat. If the connection does not receive a heardbeat within
//N*2 then the connection is considered dead.
//suggested from http://public.hudl.com/bits/archives/2013/11/11/c-rabbitmq-happy-servers/
};
var con = new AutorecoveringConnection(factory);
con.init();
return con;
})
.InSingletonScope();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With