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 つだけ使用したいので (より多くの taskitem があるため)、異なるタイプを 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)

もちろん、タスクの種類ごとに一連のクラスを作成するために、このオブジェクトに対して何らかの処理を行う必要があると思います。処理ロジックが共通である場合は、1 つの汎用クラスを作成することもできます。あなたはそのようにすることができます:

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 を作成するコメントの方法で要求されたとおり。これは、Processor 抽象クラスの静的リストになります。

私が言ったように、あなたには2つの選択肢があります

  1. たとえば、手動で行います。

    AllProcessors = 新しいリスト{typeof(Task1Processor),typeof(Task2Processor)}

  2. リフレクションを使用して、IProcessor から派生したすべての型を見つける

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

もちろん、2 番目のオプションは IProcessor が定義されたアセンブリからのみ型を取得しますが、それは非常に簡単に拡張できます。

于 2014-02-25T09:46:02.903 に答える