0

我正在处理将数据存储在 azure 队列存储中,为此目前我有 2 个数据类型类,如下所示

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

并且为了将记录插入队列,我正在使用以下方法

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

我需要从不同的队列中读取

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

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

在这里,我只想使用 1 个队列存储(因为会有更多的任务项)所以任何人都可以建议我如何将不同类型的对象组合到一种类型的对象中?

注意:ToBinary 和 FromMessage 是简单的扩展

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

谢谢。

4

1 回答 1

2

我对 CloudQueueMessage 不熟悉,但据我所知,它存储 byte[] 这意味着它不关心很好的类型,因为您可以将方法用于不同的对象,例如:

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

使用泛型方法,您不必指定类型编译器会弄清楚。除了序列化器,它可以只是对象。

现在,如果您将 FromMessage 方法转换为仅返回对象,那么无论类型如何,您都可以调用它。

var obj= FromMessage<object>(msg)

当然,我假设您需要对此对象进行一些处理,因为您可以为每种任务类型创建一组类,或者如果处理逻辑可以通用,则可以创建一个通用类。你可以这样做:

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>
{
     .....
}

然后,无论您从队列中获得什么任务,都可以使用反射来找到正确的处理器。然后像这样执行它:

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

AllProcessors 是系统中所有处理器类型的列表。您可以手动生成它,也可以通过反射扫描所有派生自 Processor<> 的类型来生成它

查询的假设是所有处理器都将直接从 Processor<> 派生,而 obj 是一个对象形式的队列。

希望有帮助

编辑

按照评论方式要求创建 AllProcessorsList。这将是处理器抽象类的静态列表。

正如我所说,你有两个选择

  1. 手动执行,例如:

    AllProcessors = 新列表{typeof(Task1Processor),typeof(Task2Processor)}

  2. 使用反射查找从 IProcessor 派生的所有类型

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

当然,第二个选项只会从定义 IProcessor 的程序集中获取类型,但您可以非常轻松地扩展它。

于 2014-02-25T09:46:02.903 回答