We've started investigating the use of the Windows Azure Service Bus as a replacement for our current queues as we move towards a service orientated architecture.
Most of the documentation is clear; however I having a hard time ascertaining which type of serialization the BrokeredMessage
uses when provided with a body.
For example, let's say I instantiate a BrokeredMessage
object as below:
ICommand sendMessageCommand = new SendMessageCommand
{
Title = "A new message title",
Body = "A new message body"
};
BrokeredMessage brokeredMessage = new BrokeredMessage(sendMessageCommand);
queueClient.Send(brokeredMessage);
SendMessageCommand
is a simple DTO marked with the [Serializable]
attribute; in our old queues this was binary serialized so it could be stored faster and have it's meta data preserved. This is important to us as we use the queues to send commands using the pattern outlined here with the receiving Worker Role deserialzing the command with a mixture of generics and dynamic typing.
However according to THIS article the body passed in to the constructor of the BrokeredMessage
is "Binary XML Serialized". My assumption then is that this is standard XML serialization then passed through a binary formatter, is that correct?
Further to this; does that mean that if I was to use the default BrokeredMessage
message body functionality; I would have to ensure all objects are XML Serializable, inclusive of all the issues that presents? (Loss of private fields, no meta data for deserializing using generics, xml serialization attributes)
Finally; if this is the case; is there a simple way around this? I was considering doing our own binary serialization then storing the byte[]
in a property on the BrokeredMessage
.
According to the documentation:
An application can set the body of the message by passing any serializable object to the constructor of the BrokeredMessage, and the appropriate DataContractSerializer will then be used to serialize the object. Alternatively, a System.IO.Stream can be provided.
The constructor you're using has this documentation:
Initializes a new instance of the BrokeredMessage class from a given object by using DataContractSerializer with a binary XmlDictionaryWriter.
This fits well with messages defined as DataContracts, as explained in this article.
Alternatively you could use surrogates as described in this answer.
You can also provide your own serializer or a stream.
An alternative would be to do your own serialization and use a byte array or string as the serializable object provided to the constructor (as opposed to in a message property). This is an adequate approach for interoperability, since you can use serialization formats such as JSON or protobuf. Microsoft's own Best Practices for Performance in Windows Azure Applications recommends using custom or third-party serialization when it impacts performance.
I've had good results using JSON serialization and dynamic objects.