2

I have a queue in Azure storage and I want to be able to add different message types to the queue and parse them as their specific types.

For example.

public class Customer
{
   public Customer()
   {
   }

   public string Name { get; set;}
   public string Email { get; set;}
   public string Address { get; set;}
}

public class Employee
{
   public Employee()
   {
   }

   public string Id { get; set;}
   public string Name { get; set;}
   public string Email { get; set;}
}

I can serialize them to JSON and add them to the queue, but how can I deserialize them to their specific types without knowing the type of the message?

How can I know that the next message is Customer or Employee? Can I add some kind of property to the message saying: "This is Customer" or "This is Employee" ...

Because I have a worker role that will look for messages in the queue and do specific action based on the type

get message from queue

If message = customer
  do this
else if message = employee
  do that
else 
  do nothing
Snympi
  • 859
  • 13
  • 18
David Dury
  • 5,537
  • 12
  • 56
  • 94

3 Answers3

1

I did the following in a project.

Store the type of message as a property of the BrokeredMessage (where entity is the class that I want to send):

var msg = new BrokeredMessage(entity);
msg.ContentType = entity.GetType().AssemblyQualifiedName;
myClient.Send(msg);

At the receiver, I have this extension method to get the message as the correct type:

public static object GetBodyOfType(this BrokeredMessage msg)
{
    var ofType = Type.GetType(msg.ContentType);
    var method = typeof(BrokeredMessage).GetMethod("GetBody", new Type[] { });
    var generic = method.MakeGenericMethod(ofType);
    return generic.Invoke(msg, null);
}

My actual receiver then does this (receivedMessage is a BrokeredMessage):

var msg = receivedMessage.GetBodyOfType();

which gives me msg which is of the type I queued.

The pattern I use this for is similar to what you describe. I queue commands to the ServiceBus, and have a single Worker Role that processes whatever command it received via a Command Handler. So far, it is working very well.

EDIT: I just realized that you mentioned Storage Queues, whereas the above is what I use for Service Bus. Hopefully the solution will apply.

Brendan Green
  • 11,676
  • 5
  • 44
  • 76
  • 1
    Your solution applies, except he needs to create his own wrapper data type. The wrapper can expose information about the message type, just as the BrokeredMessage type does. – RMD Jul 03 '14 at 00:30
1

Azure Storage Client Library does not provide explicit support for deserializing queue messages. Hence, please check the serializer you use for this. For example, if you are using DataContractSerializer, you can use known types to handle inheritance during serialization/deserialization.

Serdar Ozler
  • 3,752
  • 17
  • 24
1

I did that in the past. I've recorded the type of the object as a string into the message, then added some separator symbol: # then added json-serialised string.

So my message would look like this:

MyProject.Domain.Model.Product#{'Id':'42','ProductName':'SuperHumanEnchancer'}

and on the way back, you read whatever before separator symbol and treat it as a type name. String after separator symbol would be your json-serialised string.

trailmax
  • 34,305
  • 22
  • 140
  • 234