David Dury
David Dury

Reputation: 5717

Azure Storage Queue - CloudQueueMessage different types

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

Upvotes: 2

Views: 2042

Answers (3)

trailmax
trailmax

Reputation: 35126

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.

Upvotes: 1

Serdar Ozler
Serdar Ozler

Reputation: 3800

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.

Upvotes: 1

Brendan Green
Brendan Green

Reputation: 11954

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.

Upvotes: 1

Related Questions