2

ルーティングAPIをオーバーホールしているカスタムMVCフレームワークがあります。私は、デリゲートとジェネリックを多用するフレームワークで「セットアップ」と「実行」を分離するためのクリーンな方法を考えようとしています。今、私はこれを呼び出し側から想像しています:

//setup
MyRouter.AddRoute("/foo", () => new MyHandler(), (h) => h.MyMethod);
//h.MyMethod only exists in MyHandler, not in HttpHandler
//execution
MyRouter.Execute(HttpContext);

現在、AddRouteメソッドのシグネチャを「機能」させることができます。

delegate T HandlerInvoker<T>();
delegate string HandlerCallMethod<T>(T handler);
...
public void AddRoute<T>(string pattern, HandlerInvoker<T> invoker, HandlerCallMethod<T> caller) where T is HttpHandler{...}

呼び出し元と呼び出し元を保存する必要がなく、問題なく実行できる場合は、これで問題ありません。ただし、後で実行するために、呼び出し元と呼び出し元を保存する必要があります。

私がやろうと思った現在のこと:

  • それらをに保存し、List<object>リフレクションを使用してそれらを呼び出します。これは非常に複雑で、おそらくパフォーマンスがあまり良くないようです
  • 実行に移りAddRouteます。これは私のAPIを使用する人々にとって困難になる可能性がありますが、私の唯一の「良い」選択になる可能性があります
  • SOの質問をする:)

これらの一般的なタイプを大量の苦痛な反省なしに保存する良い方法はありますか?

4

1 に答える 1

1

すべての変換を実行する匿名の代理人を保存できます。

次のように機能するようです(テストされていません)。

List<Action> handlers;
handlers.Add(() => caller(invoker()));

キャッシュしている場合、これは機能しないことに注意してくださいinvoker

その場合、値を保持する必要がLazyあり、トリックを実行する必要があります。

List<Action> handlers;
Lazy<T> lazy = new Lazy<T>(invoker);
handlers.Add(() => caller(lazy.Value);

後者はinvoker、メソッドの呼び出しごとにの戻り値のインスタンスを1つだけ作成します。また、lazyはローカル変数であるため、参照を保持している限りhandlers保持されるクラスに自動的に押し込まれます。

パターンを無視したことに注意してください。ただし、そこでは何の助けも必要ないようです。

于 2013-02-12T04:13:52.093 に答える