Response.Redirect
層の分離を正しく保ちながら、Model-View-Presenter パターンでa を呼び出す最良の方法は何ですか?
4 に答える
Succeeded
私がこれを処理した 1 つの方法は、ビューがサブスクライブするイベント (など) をプレゼンターが発生させることです。プレゼンターが処理を終了すると、ビューによって処理されるイベントが発生します。そのハンドラーでは、ビューは次のページにリダイレクトされます。
この方法では、プレゼンターはページや URL などについて何も知る必要がありません。いつタスクが完了したかを認識し、イベントを発生させることでビューに通知します。別の場所にリダイレクトする必要がある場合に備えて、プレゼンターが成功または失敗した場合に別のイベントを発生させることができます。
概念的に、それが最も正しい方法かどうかはわかりません。しかし、前回の MVP アプリケーションで行ったことは、HttpContext.Current
HttpRedirector を呼び出すラッパーを作成することです。また、テスト用にダミーのリダイレクタも作成しました。どちらも最後にリダイレクトされた URL を追跡するため、コントローラー/プレゼンターでメソッドを呼び出したときにリダイレクトが実際に発生したことを単体テストで確認できます。IRedirector
IOCコンテナを使用すると、環境(本番/テスト)に基づいて実装を切り替えることができます。
いくつかの基礎工事が行われると、私たちのやり方はうまく機能します。猫の皮をむく方法はいくつかあると思います。(とにかく猫の皮をむく人。猫はかわいくて抱きしめたくなる!)
まず、これは Web サイトではなく、ASP.Net でコンパイルされた Web プロジェクトでのみ機能します。
各ページは、次のようなカスタム抽象基本クラスから継承する必要があります。
public abstract class PageBase : Page
{
private static string _baseUrl = "/";
public static string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected static string BuildUrl(string basePath)
{
if( !string.IsNullOrEmpty(basePath) && basePath.StartsWith("~/"))
{
basePath = basePath.replace("~/", BaseUrl);
}
return basePath;
}
protected static string LoadView(string path)
{
Response.Redirect(path);
}
}
各ページには、ページ固有のインターフェイスも実装されています。各ページ固有のインターフェースも基本インターフェースから継承します。
public interface IPageBase()
{
void LoadView(string path);
}
次に、各ページで独自のバージョンの BaseUrl を定義する必要があります。クエリ文字列/パス暗号化などを考慮したい場合があります。
最後に、プレゼンター (ページ固有のインターフェイスを参照する必要があります) は、目的のページで静的な BuildUrl() を取得して表示し、返されたパスで LoadView() を呼び出すことができます。
プレゼンターがどれほど一般的かによって異なります。プレゼンターが完全に UI にとらわれない (WinForms と WebForms の間で再利用できる) 場合は、リダイレクト操作を抽象化する必要があります。WebForms では、リダイレクト操作は Response.Redirect によってビューに実装されます。WinForms では、(WinForms に関する多くの経験は省きます) 私の推測では、これは SomeForm.Show によって実装されるでしょう。
1 つの簡単で思いつきのオプションは、ビューのインターフェイスに ShowViewX() メソッドを含めることです。ビューが論理的にリダイレクトできるフォームごとに 1 つ持つことができます。または、ビューは Show(ConnectedViews) のようなインターフェイス メソッドを実装できます。ConnectedViews は、特定のビューから「リダイレクト」できる各ビューの値を含む列挙型です。この列挙型は、プレゼンター レベルに存在します。
上記のアプローチは、ビューとプレゼンターのペアに固有のものです。代わりに、システム全体のものとして実装できます。ロジックは上記と同様で、ベース ビューとプレゼンターに実装されます。各フォームに ShowView__() があるか、Views がすべてのフォームの列挙型である Show(Views) メソッドがあります。
カプセル化とドライネスの間のトスアップです.