2009-05-27 22 views
7

私は、ASP.NET MVCに移植したいバニラASP.NETで書かれたアプリケーションを持っています。ASP.NET MVCセッションとグローバルvsキャッシュ

しかし、私はオブジェクトを永続させるための正しい場所について混乱しています。私はカップルの理由のために存続する必要があります。

  1. 私はすべてが「リポジトリ」または「マネージャ」スタイルのオブジェクトにラップ単一データベース接続を、持っていると思います。
  2. 各ユーザーには、セッションごとに保存する必要があるユーザーオブジェクトがあります。

通常、#1は、Global.RepositoryなどでヒットできるGlobals.asaxに静的なアイテムとして保存されると言います。

そして、私は通常、#2はページの基本クラスのどこかにセッションバッキングストアを持つプロパティでなければならないと言います。

私が混乱している理由は、セッションがMVCで変更されたと聞き、Global.asaxが同じクラスを保持していないということです。また、ページのコンセプトが削除されているため、コントローラの基本クラスにプロパティを追加するのは間違っているようです。

yallとは何ですか?

答えて

10

データベースは、コントローラの基本クラスになります。この基本クラスはControllerを拡張する必要があり、すべてのコントローラは基本クラスを拡張する必要があります。ちょっとした例です:

public class BaseController : Controller 
{ 
    private AuthServices _auth; 
    private LogHelper _log; 
    private Repository _repository; 

    /// <summary> 
    /// <see cref="AuthServices"/> 
    /// </summary> 
    protected AuthServices Authorization 
    { 
     get { return _auth ?? (_auth = new AuthServices()); } 
    } 

    /// <summary> 
    /// <see cref="LogHelper"/> 
    /// </summary> 
    protected LogHelper Log 
    { 
     get { return _log ?? (_log = new LogHelper()); } 
    } 

    /// <summary> 
    /// <see cref="Repository"/> 
    /// </summary> 
    protected Repository Repository 
    { 
     get { return _repository ?? (_repository = new Repository()); } 
    } 
} 

遅延インスタンス化に注目してください。それは私がテストを実行する前に忍び込んで私のプライベートフィールドをモックで設定することができます。

セッションに関しては、従来のASP.NETアプリケーションと同じように、ユーザーオブジェクトをセッションに保存することができます。ほぼすべてが(レスポンス、キャッシュ、セッションなど)周辺にありますが、一部はSystem.Web.Abstractionsのクラスでラップされているため、テストのために嘲笑することができます。これらはすべて同じ方法で動作しますが、従来の役割(たとえば、Response.Redirectを使用しないで、リダイレクトを実行するRedirectToRouteResultなどのActionResultを返すなど)では使用しないでください。ご質問の背後にある理由については

....

は、単一のDB接続でストレスをしないでください。あなたの実装によっては、リクエストがお互いに進む可能性があるので、それは悪い考えかもしれません。コネクションを開いて使用し、完了したらそれを破棄してください。

MVCがもたらす最も大きな変化の1つは、従来のASP.NETがWeb開発にもたらしたステートフルモデルの拒否です。そのフレームワークとビューステートはもう存在しません(カーテンの後ろの人には注意を払わないでください)。より複雑ではなく、より堅牢なWebアプリケーションを保持する状態が少なくなる。それを試してみてください。

+1

"テストを実行してプライベートフィールドをモックで設定する前に、怠惰なインスタンス化を行うことができます。なぜIoCを使用しないのですか? –

+1

赤ん坊のステップ......あなたはこれを行う例で答えるべきです。 – Will

+1

私は実際に接続プーリングを使用します。とにかく、ありがとう。これはほぼ正確に私が計画していたもので、私はベストプラクティスにかなり近いと知っています。 –

2

セッションはMVCではまったく変更されていません。 Global.asaxのGlobalApplicationクラスもまだ存在します。また、ページではなくコントローラのリポジトリを参照するページが存在します。ベースコントローラクラスにプロパティを追加するのは問題ありません。私はいつもそれをする。

4

セッションを使用する場合は、セッションクラスを使用することをお勧めします。これにより、コードで文字列名を1回指定するだけでIntelliSenceも得られます。

public static class SessionHandler 
{ 
    // User Values 
    private static string _userID = "UserID"; 
    private static string _userRole = "UserRole"; 

    public static string UserID 
    { 
     get 
     { 
      if (HttpContext.Current.Session[SessionHandler._userID] == null) 
      { return string.Empty; } 
      else 
      { return HttpContext.Current.Session[SessionHandler._userID].ToString(); } 
     } 
     set 
     { HttpContext.Current.Session[SessionHandler._userID] = value; } 

    } 

    public static string UserRole 
    { 
     get 
     { 
      if (HttpContext.Current.Session[SessionHandler._userRole] == null) 
      { return string.Empty; } 
      else 
      { return HttpContext.Current.Session[SessionHandler._userRole].ToString(); } 
     } 
     set 
     { HttpContext.Current.Session[SessionHandler._userRole] = value; } 

    } 
} 
+0

私はこれが好きですが、各コントローラに対してインスタンスを作成する必要があります。セッションのすべてのコントローラにセッションベースのオブジェクトを共有させるので、BaseControllerクラスのプロパティとしてそれらを配置します。 –

1

状態をカプセル化するためのモデルバインダーを作成できます。

(彼のショッピングカートの実装上のスティーブ・サンダーソンのMVCの本を参照してください)

モデルバインダーを使用すると、controllerContextへのアクセス持っている - のHttpContextを持っています。

関連する問題