Monthly Archives: July 2010

New version of the WCFMsmqFactory

Based on the comments I recieved on the article:

Create a WCF service and client, using Msmq, programmatically I’ve updated the MsmqFactory class.

 

Here is the new version:

using System; using System.Messaging; using System.ServiceModel; using System.ServiceModel.MsmqIntegration;

namespace BelgianAgencies.Wcf
{
    public class WcfMsmqFactory<I>
    {
        private string _queueAddress;
        private string _netmsmqAddress;
        public WcfMsmqFactory(string queueName)
        {
            _queueAddress = String.Format(@".\private$\{0}", queueName);
            _netmsmqAddress = String.Format(@"msmq.formatname:DIRECT=OS:{0}", _queueAddress);
            if (!MessageQueue.Exists(_queueAddress))
                MessageQueue.Create(_queueAddress, true);
        }
        public bool UseCustomDeadLetterQueue
        {
            get;
            set;
        }
        /// <summary>
        /// Is the queue on a device connected to active directory.
        /// Standard = false.
        /// </summary>
        /// <value><c>true</c> if [in active directory]; otherwise, <c>false</c>.</value>
        public bool InActiveDirectory
        {
            get; set;
        }
        public ServiceHost CreateService<T>(string namespaceName)
        {
            var sHost = new ServiceHost(typeof(T));
            MsmqIntegrationBinding binding;
            binding = InActiveDirectory ? new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.Transport) : new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
            // Retry at most 5 times
            binding.ReceiveRetryCount = 1;
            // Max amount of retries before cancel message
            //  (1 + MaxRetryCycles) * (ReceiveRetryCount + 1) = total amount of retries
            binding.MaxRetryCycles = 3;
            // time before timout when unable to get message out of the queue
            binding.ReceiveTimeout = new TimeSpan(0, 0, 5);
            // when unable to dequeue put message on dead letter queue
            //TODO: set to reject on msmq 4.0
            binding.ReceiveErrorHandling = ReceiveErrorHandling.Fault;
            // this message is not volatile, when hard reboot message will not get lost
            binding.Durable = true;
            // timout when opening connection
            binding.OpenTimeout = new TimeSpan(0, 0, 5);
            // timout when closing connection
            binding.CloseTimeout = new TimeSpan(0, 0, 5);
            binding.Namespace = namespaceName;
            sHost.AddServiceEndpoint(
                typeof(I),
                binding,
                new Uri(_netmsmqAddress)
                             );
            return sHost;
        }
        public I CreateChannel()
        {
            var binding = new MsmqIntegrationBinding(MsmqIntegrationSecurityMode.None);
            var address = new EndpointAddress(String.Format("msmq.formatname:DIRECT=OS:{0}", _queueAddress));
            var channelFactory = new ChannelFactory<I>(binding, address);
            return channelFactory.CreateChannel();
        }
    } 
}