Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Message Queues with different message types

Tags:

c#

msmq

I'm investigating Microsoft Message Queues for doing inter-process cross-network messaging. But when I receive a message, I don't know a priori what type of object I'm getting, so the code

queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Wibble) });

can't be applied before I get the message because I don't know if it's a Wibble. So how do I receive different message types?

like image 762
Julian Gold Avatar asked May 29 '12 11:05

Julian Gold


2 Answers

You're already using the constructor overload for XmlMessageFormatter that accepts an array of types. So just add all of the types that you're expecting to receive into that array, rather than just one type.

queue.Formatter = new XmlMessageFormatter(new Type[] {
    typeof(Wibble),
    typeof(Fleem),
    typeof(Boo)
});

From TargetTypes:

The instance serialized in the message body must comply with one of the schemas represented in the type array. When you read the message using the Receive method, the method creates an object of the type that corresponds to the schema identified and reads the message body into it.

(Emphasis added)

like image 176
Damien_The_Unbeliever Avatar answered Oct 05 '22 17:10

Damien_The_Unbeliever


You might consider not storing your object in the MSMQ message, but instead putting a reference to it's persistent location if you can. MSMQ has finite space on the message queues, so smaller messages are best.

If you can't do that, you can serialize your object to the messages BodyStream directly, using whatever serializer you like. Then store the type name as well, probably best in the message Label.

Something very similar to this (scratched it out here, no IDE on this computer) to put it in, and the analagous action on the way out:

public void FormatObject(object toFormat, Message message)
{
    var serializer = new XmlSerializer(toFormat.GetType());
    var stream = new MemoryStream();
    serializer.Serialize(toFormat, stream);

    //don't dispose the stream
    message.BodyStream = stream;
    message.Label = toFormat.GetType().AssemblyQualifiedName;
}
like image 29
tallseth Avatar answered Oct 05 '22 17:10

tallseth