How to use one object to store multiple type of data

十年热恋 提交于 2019-12-25 01:54:02

问题


I am dealing to store data in azure queue storage and for that currently i have 2 data types classes as below

  [Serializable]
    public class Task1Item
    {
        public int ID { get; set; }
        public string Company { get; set; }
        ------
        ------
    }

   [Serializable]
    public class Task2Item
    {
        public int ID { get; set; }
        public string connectTo{ get; set; }
        public string Port{ get; set; }
        ------
        ------
    }

and for inserting record to queue i am using below methods

  // For Task1Item
  CloudQueueMessage msg = new CloudQueueMessage(item1.ToBinary<Task1Item>());
   // For Task2Item
  CloudQueueMessage msg = new CloudQueueMessage(item2.ToBinary<Task2Item>());

and i need to read from different queues

  var item1 = cloudQueueMessage1.FromMessage<Task1Item>();

  var item2 = cloudQueueMessage2.FromMessage<Task2Item>();

Here i would like to use only 1 queue storage (as there will be more taskitem) so can any one please suggest me how can i combine different types to one type of object?

Note: ToBinary & FromMessage are simple extensions

 public static byte[] ToBinary<T>(this T dns)
        {
            var binaryFormatter = new BinaryFormatter();
            byte[] bytes = null;
            using (var memoryStream = new MemoryStream())
            {
                binaryFormatter.Serialize(memoryStream, dns);
                bytes = memoryStream.GetBuffer();
            }

            return bytes;
        }

        public static T FromMessage<T>(this CloudQueueMessage cloudQueueMessage)
        {
            var bytes = cloudQueueMessage.AsBytes;
            using (var memoryStream = new MemoryStream(bytes))
            {
                var binaryFormatter = new BinaryFormatter();
                return (T)binaryFormatter.Deserialize(memoryStream);
            }
        }

Thanks.


回答1:


I'm not familiar with CloudQueueMessage but from what i can see it stores byte[] which means that it doesn't care about types that's good cos you can use your methods for different objects like:

var msg = new CloudQueueMessage(item1.ToBinary());
var msg1 = new CloudQueueMessage(item2.ToBinary());

With generic method you don't have to specify type compiler will figure it out. Beside with serializer it can just be object.

Now if you convert your FromMessage method to just return object and then you can call it regardless of type.

var obj= FromMessage<object>(msg)

Of course I assume that you need to do some processing on this object for that you could create set of classes for each task type or maybe one generic one if the processing logic can be common. You could do it like that :

public interface IProcessor
{
    void Process(object obj);
}

public abstract class Processor<T>, IProcessor
{
    public void Process(T obj);
    public void Process(object obj)
    {
        Process((T)obj);
    }
}

public class Task1Processor:Processor<Task1>
{
     .....
}

Then wherever you get task from the queue you use reflection to find correct processor. And then execute it like:

var processorType = AllProcessors.FirstOrDefault(p=>p.BaseType.GetGenericParameters()[0]==obj.GetType())
var processor = (IProcessor)Activator.CreateInstance(processorType);
processor.Process(obj);

AllProcessors is a list of all processors types that you have in the system. You can generate it manually or by reflection scanning all types that derive from Processor<>

Assumption with query are that all processors will directly derive from Processor<> and obj is a object form queue.

Hope that helps

Edit

As requested in comment way to create AllProcessorsList. It would be a static list on Processor abstract class.

As I said you have two options

  1. Do it manually for example:

    AllProcessors = new List{typeof(Task1Processor),typeof(Task2Processor)}

  2. Use reflection to find all types that derive from IProcessor

    AllProcessors = typeof(IProcessor).Assembly.GetTypes().Where(t=>typeof(IProcessor).IsAssignableFrom(t)).ToList();

Of course second option will only get types from assembly where IProcessor was defined but you can extend that very easily.



来源:https://stackoverflow.com/questions/22008151/how-to-use-one-object-to-store-multiple-type-of-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!