MSMQ Logging and Entlib with Remote Private queues

As I have stated before, the client I am at has recently decided to adopt EntLib into their development standards.  It was not an easy decision for them and it took quite a bit of discussion on the matter.  The first part that is being absorbed by the standards is the Logging and Exception Handling blocks.  The client has chosen to use the MSMQ distribution strategy for logging in order to centralize the logs of all their applications into one database.

Based on MSMQ best practices we recommended using private queues instead of public ones.  This cuts down the necessity for Active Directory to be involved.  The client had not previously been using MSMQ in any of their current systems.  This lead to an issue about communication with Remote Private queues.  Basically the issue is the MSMQ Distribution Strategy for EntLib out of the box will NOT work with remote private queues.  Here’s why:  to hit a remote private queue with EntLib (which is using System.Messaging under the hood) we had to use the FormatName option of Direct.  The Direct communications does NOT allow for the querying of queue properties.  Also, you can NOT query the queue properties of a remote private queue by design.  The MsmqLogDistributionStrategy class used to send the messages uses the following bit of code in it’s SendMsmqMessage method:

                    MessageQueueTransactionType transactionType = (messageQueue.Transactional)
                        ? MessageQueueTransactionType.Single
                        : MessageQueueTransactionType.None;

                    messageQueue.Formatter = new XmlMessageFormatter();
                    messageQueue.Send(serializedEntry, transactionType);
                    messageQueue.Close();

This creates an instance of the queue as a reference on the client.  It them checks the queue to see if the it is Transactional or not.  As stated before you CAN NOT check the properties of a private remote queue, or any queue you connect with using the FormatName option of Direct.  This code was causing an exception and the messages were not being sent to our remote private queue.

How to fix this?

Well, we discussed several options and the client choose to go with public queues, which nullifies the issue since you can connect to the public queue with just computername\queuename instead of having to use the FormatName option Direct.  It does mean that they have to have some reliability on their AD to be up and running at all times and that now the queue is discoverable in AD.  It will also decrease performance of the queue as the MSMQ client software will query the AD for information before sending the message.

Now, if you really want to use EntLib logging MSMQ distribution strategy with a remote private queue here is the other option we suggested.  Create a new class that duplicates the MsmqLogDistributionStrategy class and remove the check of the transactional type.  We toyed with inheriting from the MsmqLogDistributionStrategy class, but found that other issues came up with having to get at private members within the MsmqLogDistributionStrategy in the derived class, such as the configuration data, etc.  It’s such a small class anyway that just copying the class, renaming it and then modifying it was a decent option for us.

Why the check for the queue being transactional is being done I’m not quite sure.  Hopefully this will help someone else.  Also, if you find that I’ve stated anything incorrectly here, or know of another way you plan on handling this, please leave a comment.