DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
WCF MSMQ Factory Class
/// <summary>
/// WCF MSMQ Factory class, waarmee zowel server als client programmatisch aangemaakt kunnen worden.
/// Gebaseerd op een idee van Geoffrey Vandiest
/// (http://geoffrey.vandiest.biz/post/Create-a-WCF-service-and-client-using-Msmq-programmatically.aspx).
/// Zie ook http://www.devx.com/enterprise/Article/39015/1954 voor een overzicht van de architectuur.
///
/// </summary>
/// <typeparam name="I">ServiceInterface</typeparam>
public class WCFMessagingQueueFactory<I>
{
private string _netmsmqAddress;
private string _netmsmqDLQAddress;
private TimeSpan _timeToLive = new TimeSpan(24, 0, 0);
private bool _inActiveDirectory = false;
/// <summary>
/// Specificeert of deze queue vanuit een machine in een activedirectory benaderd wordt,
/// of via een machine die alleen aan een workgroup verbonden is.
/// Standaard waarde = false.
/// Zie:
/// http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.netmsmqbindingelement.useactivedirectory.aspx
/// http://msdn.microsoft.com/en-us/library/ms585430.aspx
/// http://msdn.microsoft.com/en-us/library/system.servicemodel.netmsmqsecuritymode.aspx
/// </summary>
/// <value><c>true</c> if [in active directory]; otherwise, <c>false</c>.</value>
public bool InActiveDirectory
{
get { return _inActiveDirectory; }
set { _inActiveDirectory = value; }
}
/// <summary>
/// TimeToLive bepaalt hoe lang een bericht in de queue blijft na verzenden. Nadat
/// TimeToLive verstreken is wordt het bericht in de custom deadletter queue geplaatst.
/// </summary>
/// <value>The time to live.</value>
public TimeSpan TimeToLive
{
get { return _timeToLive; }
set { _timeToLive = value; }
}
/// <summary>
/// Constructor van <see cref="WCFMessagingQueueFactory<I>"/> class.
/// </summary>
/// <param name="queueName">Naam van de queue.</param>
[MessageQueuePermission(SecurityAction.Demand, Unrestricted=true)]
public WCFMessagingQueueFactory(string queueName)
{
string _msmqAddress = String.Format(@".\private$\{0}", queueName);
_netmsmqAddress = String.Format(@"net.msmq://localhost/private/{0}", queueName);
string _msmqDLQAddress = String.Format(@"{0}DLQ", _msmqAddress);
_netmsmqDLQAddress = String.Format(@"{0}DLQ", _netmsmqAddress);
if (!MessageQueue.Exists(_msmqAddress))
MessageQueue.Create(_msmqAddress, true);
if (!MessageQueue.Exists(_msmqDLQAddress))
MessageQueue.Create(_msmqDLQAddress, true);
}
/// <summary>
/// Maakt een server aan.
/// </summary>
/// <param name="namespaceName">Naam van de namespace.</param>
/// <returns></returns>
public ServiceHost CreateServer<T>(string namespaceName)
{
var sHost = new ServiceHost(typeof(T));
NetMsmqBinding binding = null;
if (InActiveDirectory)
{
binding = new NetMsmqBinding(NetMsmqSecurityMode.Transport);
}
else
{
binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
}
// Hier worden de binding variabelen ingesteld die van belang zijn voor de server
// zie http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.netmsmqbindingelement_members.aspx
// probeer maximaal 5 keer het bericht uit de queue op te halen
binding.ReceiveRetryCount = 1;
// maximaal aantal pogingen om bericht uit de queue op te halen.
// (1 + MaxRetryCycles) * (ReceiveRetryCount + 1) = totaal aantal pogingen.
binding.MaxRetryCycles = 3;
// als het ophalen na 5 seconden niet gelukt is, timeout exceptie
binding.ReceiveTimeout = new TimeSpan(0, 0, 5);
// als het ophalen niet lukt, stuur het bericht dan door naar de custom deadletter queue
binding.ReceiveErrorHandling = ReceiveErrorHandling.Reject;
// deze queue is niet volatile (alleen in geheugen), bij stroomstoring is het bericht er nog
binding.Durable = true;
// toegestane tijdspanne voor openen verbinding
binding.OpenTimeout = new TimeSpan(0, 0, 5);
// toegestane tijdspanne voor sluiten verbinding
binding.CloseTimeout = new TimeSpan(0, 0, 5);
binding.Namespace = namespaceName;
ServiceEndpoint serviceEndPoint = sHost.AddServiceEndpoint(typeof(I),
binding,
new Uri(_netmsmqAddress)
);
return sHost;
}
/// <summary>
/// Maakt een client.
/// </summary>
/// <param name="namespaceName">Name van de namespace.</param>
/// <returns></returns>
public ChannelFactory<I> CreateClient(string namespaceName)
{
var binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
// Hier worden de binding variabelen ingesteld die van belang zijn voor de client
// zie http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.netmsmqbindingelement_members.aspx
// levensduur bericht
binding.TimeToLive = TimeToLive;
// er wordt maximaal 1 keer een bericht aangeboden, bij fouten direct door naar deadletter queue
binding.ExactlyOnce = true;
// deze queue is niet volatile (alleen in geheugen), bij stroomstoring is het bericht er nog
binding.Durable = true;
// er wordt een eigen deadletter queue aangeboden
binding.DeadLetterQueue = DeadLetterQueue.Custom;
// het adres van de eigen deadletter queue
binding.CustomDeadLetterQueue = new Uri(_netmsmqDLQAddress);
// de namespace
binding.Namespace = namespaceName;
// gebruik geen active directory om de naam van de queue om te zetten.
binding.UseActiveDirectory = InActiveDirectory;
// toegestane tijdspanne voor openen verbinding
binding.OpenTimeout = new TimeSpan(0, 0, 5);
// toegestane tijdspanne voor sluiten verbinding
binding.CloseTimeout = new TimeSpan(0, 0, 5);
var address = new EndpointAddress(String.Format(_netmsmqAddress));
var channelFactory = new ChannelFactory<I>(binding, address);
return channelFactory;
}
}





