.NET MSMQ - 1.1
Description
This extension provides support for MSMQ .NET APIs which are responsible for send and receive operations in .NET applications. If your C# application utilizes MSMQ for messaging-related operations, the send and receive are handled using the C# language, and you want to modelize the sender and receiver links with appropriate objects and links, then you should install this extension.
Supported libraries
| Library | Version | Supported |
|---|---|---|
| System.Messaging | up to: 4.x | ✅ |
| MSMQ.Messaging | up to 1.x | ✅ |
| Experimental.System.Messaging | up to 1.x | ✅ |
| NServiceBus | up to 9.2.x | ✅ |
Function Point, Quality and Sizing support
- Function Points (transactions): a green tick indicates that OMG Function Point counting and Transaction Risk Index are supported
- Quality and Sizing: a green tick indicates that CAST can measure size and that a minimum set of Quality Rules exist
| Function Points (transactions) | Quality and Sizing |
|---|---|
| ✅ | ❌ |
Dependencies with other extensions
Some CAST extensions require the presence of other CAST extensions in order to function correctly. The .NET NMS extension requires that the following other CAST extensions are also installed (this will be managed automatically):
Download and installation instructions
The extension will be automatically downloaded and installed in CAST Console. You can manage the extension using the Application - Extensions interface.

What results can you expect?
Objects
| Icon | Description |
|---|---|
![]() |
MSMQ Sender |
![]() |
MSMQ Receiver |
![]() |
MSMQ unknown Sender |
![]() |
MSMQ unknown Receiver |
Links
| Link Type | Source and Destination of link | Supported APIs |
|---|---|---|
| callLink | callLink between the caller C# method and the Sender object |
Sender APIs
|
| callLink | callLink between the Receiver object and the caller C# method |
Receiver APIs
|
Example code scenarios
System.Messaging
Sender APIs
using System;
using System.Collections.Generic;
using System.Messaging;
using Castle.Windsor;
using DddCqrsEsExample.Framework;
using Newtonsoft.Json;
namespace DddCqrsEsExample.Web2.Infrastructure
{
public class MsmqEventBus : IEventBus
{
private readonly IWindsorContainer _container;
private const string QueueName = @".\private$\DddCqrsEsQueue";
public MsmqEventBus(IWindsorContainer container)
{
if (container == null) throw new ArgumentNullException(nameof(container));
_container = container;
}
public void Publish<TEvent>(TEvent evt) where TEvent : Event
{
HandleEvent(evt);
PublishOnMsmq(evt);
}
private void HandleEvent<TEvent>(TEvent evt) where TEvent : Event
{
var handlerType = typeof(IEventHandler<>).MakeGenericType(evt.GetType());
var handlers = _container.ResolveAll(handlerType);
foreach (var handler in handlers)
{
try
{
var handleMethod = handler.GetType().GetMethod("Handle");
handleMethod.Invoke(handler, new object[] {evt});
}
finally
{
_container.Release(handler);
}
}
}
private static void PublishOnMsmq<TEvent>(TEvent evt) where TEvent : Event
{
if (!MessageQueue.Exists(QueueName))
{
MessageQueue.Create(QueueName);
}
using (var q = new MessageQueue(QueueName))
{
q.DefaultPropertiesToSend.Recoverable = true;
q.Send(JsonConvert.SerializeObject(evt, Formatting.Indented) + "|" + evt.GetType().AssemblyQualifiedName);
}
}

Receiver APIs
using System;
using System.Messaging;
using DddCqrsEsExample.Framework;
using DddCqrsEsExample.ThinReadLayer.Core;
using Newtonsoft.Json;
namespace DddCqrsEsExample.ThinReadLayer.EventListener
{
public class Listener
{
private const string QueueName = @".\private$\DddCqrsEsQueue";
private MessageQueue _listeningQueue;
public void Start()
{
if (!MessageQueue.Exists(QueueName))
{
MessageQueue.Create(QueueName);
}
try
{
if (MessageQueue.Exists(QueueName))
{
_listeningQueue = new MessageQueue(QueueName);
_listeningQueue.ReceiveCompleted +=
(sender, args) =>
{
args.Message.Formatter = new XmlMessageFormatter(new[] {typeof(string)});
var msg = args.Message.Body.ToString();
Console.WriteLine("Message received:{0}", msg);
var parts = msg.Split('|');
var json = parts[0];
var typeName = parts[1];
var type = Type.GetType(typeName);
var evt = (Event)JsonConvert.DeserializeObject(json, type);
new Denormaliser().StoreEvent(evt);
_listeningQueue.BeginReceive();
};
_listeningQueue.BeginReceive();
}
}
catch (Exception e)
{
Console.WriteLine(string.Format("Unable to initialise message queue on your local machine.\r\n\r\n{0}", e));
}
}
}
}

Dotnet Sender and Receiver
When the queue path matches for both the sender and receiver, a callLink will be established between the sender object and the receiver object:

MSMQ NServiceBus
Sender side
using System;
using System.Threading.Tasks;
using NServiceBus;
using Contracts.Commands;
class Program
{
static async Task Main()
{
var endpointConfiguration = new EndpointConfiguration("OrderEntry.Endpoint");
endpointConfiguration.UseTransport<MsmqTransport>();
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
endpointConfiguration.EnableInstallers();
var endpointInstance = await Endpoint.Start(endpointConfiguration);
var command = new PlaceOrder
{
OrderId = Guid.NewGuid().ToString(),
Product = "Laptop"
};
var options = new SendOptions();
options.SetDestination("Billing.Endpoint");
await endpointInstance.Send(command, options);
Console.WriteLine("Order command sent to Billing.Endpoint");
Console.ReadKey();
await endpointInstance.Stop();
}
}


Receiver side
using System;
using System.Threading.Tasks;
using NServiceBus;
class Program
{
static async Task Main()
{
var endpointConfiguration = new EndpointConfiguration("Billing.Endpoint");
endpointConfiguration.UseTransport<MsmqTransport>();
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
endpointConfiguration.EnableInstallers();
var endpointInstance = await Endpoint.Start(endpointConfiguration);
Console.WriteLine("Billing service is running...");
Console.ReadKey();
await endpointInstance.Stop();
}
}
using System;
using System.Threading.Tasks;
using NServiceBus;
using Contracts.Commands;
namespace Billing.Service.Handlers
{
public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
{
public Task Handle(PlaceOrder message, IMessageHandlerContext context)
{
Console.WriteLine($"Billing received OrderId={message.OrderId}, Product={message.Product}");
return Task.CompletedTask;
}
}
}


Sender and Receiver
When the Message contracts matches for both the sender and receiver, a callLink will be established between the sender object and the receiver object:

Known limitations
- Unknown Sender/Receiver objects will be created if the evaluation fails to resolve the necessary parameter.



