Очередь хранилища Azure — CloudQueueMessage разных типов

#azure #azure-storage #azure-queues #azure-storage-queues

#azure #azure-хранилище #azure-очереди #azure-очереди хранилища

Вопрос:

У меня есть очередь в хранилище Azure, и я хочу иметь возможность добавлять разные типы сообщений в очередь и анализировать их как определенные типы.

Например.

 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;}
}
  

Я могу сериализовать их в JSON и добавить в очередь, но как я могу десериализовать их до их конкретных типов, не зная типа сообщения?

Как я могу узнать, что следующее сообщение — это Клиент или сотрудник? Могу ли я добавить какое-либо свойство к сообщению, в котором говорится: «Это клиент» или «Это сотрудник»…

Потому что у меня есть рабочая роль, которая будет искать сообщения в очереди и выполнять определенные действия в зависимости от типа

 get message from queue

If message = customer
  do this
else if message = employee
  do that
else 
  do nothing
  

Ответ №1:

Я делал это в прошлом. Я записал тип объекта в виде строки в сообщение, затем добавил некоторый символ разделителя: # затем добавил строку, сериализованную в формате json.

Итак, мое сообщение будет выглядеть так:

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

и на обратном пути вы читаете все, что предшествует символу разделителя, и рассматриваете его как имя типа. Строка после символа разделителя будет вашей последовательной строкой в формате json.

Ответ №2:

Я сделал следующее в проекте.

Сохраняйте тип сообщения как свойство BrokeredMessage (где entity — класс, который я хочу отправить):

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

У получателя у меня есть этот метод расширения, чтобы получить сообщение как правильный тип:

 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);
}
  

Затем мой фактический получатель выполняет это ( receivedMessage является BrokeredMessage ):

 var msg = receivedMessage.GetBodyOfType();
  

что дает мне msg тип, который я поставил в очередь.

Шаблон, для которого я использую это, похож на то, что вы описываете. Я ставлю команды в очередь на ServiceBus и имею единственную рабочую роль, которая обрабатывает любую команду, полученную через обработчик команд. Пока все работает очень хорошо.

РЕДАКТИРОВАТЬ: я только что понял, что вы упомянули очереди хранилища, тогда как вышеописанное — это то, что я использую для служебной шины. Надеюсь, решение будет применено.

Комментарии:

1. Ваше решение применимо, за исключением того, что ему нужно создать свой собственный тип данных оболочки. Оболочка может предоставлять информацию о типе сообщения, точно так же, как это делает тип BrokeredMessage.

Ответ №3:

Клиентская библиотека хранилища Azure не предоставляет явной поддержки десериализации сообщений очереди. Поэтому, пожалуйста, проверьте сериализатор, который вы используете для этого. Например, если вы используете DataContractSerializer, вы можете использовать известные типы для обработки наследования во время сериализации / десериализации.