2

多くの異なるタイプのリクエストを受信/逆シリアル化するオブジェクト「レシーバー」があります。

次に、受信リクエストのタイプに基づいて、リクエスト オブジェクトを正しいリクエスト ハンドラ オブジェクト (以前にディスパッチャに登録済み) にディスパッチする「ディスパッチャ」オブジェクトをこのレシーバに使用してもらいたいと考えています。もちろん、リクエストのタイプはコンパイル時ではなく実行時にのみわかります(簡単すぎます;))

ここに物事を明確にするためのいくつかのコードがあります...

リクエストタイプのマーカーインターフェースがあります:

public interface IRequest {}

次に、ダミーのリクエスト タイプ:

public class DummyRequest : IRequest {}

これは、リクエスト タイプ T のリクエスト ハンドラによって使用される汎用インターフェイスです。

public interface IRequestHandler<in T> where T : IRequest
{
   void HandleRequest(T request);
}

そして、 DummyRequest リクエストのリクエストハンドラである具体的な実装:

public class DummyRequestHandler : IRequestHandler<DummyRequest>
{
   public void HandleRequest(DummyRequest request) { }
}

これは、動的を利用するディスパッチャーの非常に基本的な実装ですが、コンパイル時に要求の種類がわかっている場合にのみ機能しますが、実行時にのみ要求の種類がわかっている場合は機能しません (これはあまり重要ではありません)。私の文脈では、しかしどういうわけか意図を示しています):

public class Dispatcher
{
    private Dictionary<Type, dynamic> _handlers = new Dictionary<Type, dynamic>();

    public void Dispatch<T>(T requestObject) where T : IRequest
    {
       _handlers[requestObject.GetType()].HandleRequest(requestObject);
    }

    public void RegisterHandler<T>(IRequestHandler<T> handler) where T : IRequest
    {
       _handlers[typeof(T)] = handler;
    }
}

そして、dispatcher 変数が Dispatcher オブジェクトであることを考慮した使用法:

一部のコードは、この方法でディスパッチャーにハンドラーを登録します

dispatcher.RegisterHandler<DummyRequest>(new DummyRequestHandler());

そして、受信側オブジェクトはディスパッチャーを使用して、次のように受信リクエストをディスパッチします。

dispatcher.Dispatch(new DummyRequest());            

もちろん、ここではコンパイル時にリクエスト タイプがわかっている場合にのみ機能しますが、私のコンテキストでは、リクエストは次のようなオブジェクト タイプとしてレシーバーによって受信されます。

// Here ReceiveMessage is not generic and therefore returns object type 
// (even if type is DummyRequest, it's just being returned as an object,
// i.e : "request is DummyRequest" returns true) 
// signature of ReceiveMessage is "object ReceiveMessage()"
var request = ReceiveMessage(); 

このようにディスパッチャーを呼び出すことはできません

dispatcher.Dispatch(request); 

型の安全性を失わずにこれを回避する方法を見つけることができません (たとえば、HandleRequest 署名をオブジェクトを取る非ジェネリック署名に変更しないなど)。

私の質問が明確で理にかなっていることを願っています...おそらく本当の方法はありません。わかりません。

「リクエストディスパッチャーC#」をグーグルで検索しても、興味深いものは見つかりませんでした。この種の「パターン」は別の名前で知られているかもしれませんが、それをリクエスト ディスパッチャと呼ぶのは理にかなっています。

これの背後にある最終的な目的は、特定のリクエスト タイプの新しいリクエスト ハンドラを作成し、それをディスパッチャに登録するだけで、レシーバやディスパッチャのコードを変更することなく、新しいリクエスト タイプを処理できるようにすることです。

ありがとう !

4

2 に答える 2

2

実行時までオブジェクトタイプがわからないという事実から逃れることはできないので、それに対処する設計が必要です。ファクトリパターンを確認する必要があります。あなたがそれをグーグルするならば、あなたはたくさんの例を見つけるでしょう。ただし、本質的には、実行時にコード内のオブジェクトのタイプを把握し、インスタンス化するオブジェクトタイプを把握する必要があります。これは、Reflectionを使用するという形をとるか、ファクトリメソッド内のswitchステートメントである可能性があります。

于 2012-12-05T09:01:57.743 に答える
2

あなたができることは、抽象ファクトリパターン(ジェネリックを組み込む)を実装することです。これは、非常に簡単に概説すると、次のようになります。

public interface IRequest
{
   void Dispatch();
}

次のクラスを使用して、実行時に使用する正しい「戦略」を取得する場所

public static class DispatchStrategyfactory
{
    public static void Dispatch<T>(T instance) where T : IRequest 
    {
        instance.Dispatch();
    } 
}

ただし、このパターンを機能させるには、関連する具象クラスを次のように作成する必要があります。

public static TestDispatcher : IRequest
{
    public void Dispatch()
    {
        // Do stuff.
    }
}

これにより、必要なことを実行できるようになります。Strategy/[Abstract]Factory パターンの詳細については、こちらを参照してください。ここで要点を見逃していないことを願っています。

これが役立つことを願っています。

于 2012-12-05T09:10:49.860 に答える