7

ASP.NETMVCに移植したいバニラASP.NETで作成されたアプリケーションがあります。

しかし、私はオブジェクトを永続化するための適切な場所について混乱しています。私はいくつかの理由で固執する必要があります:

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

通常、#1は、Globals.asaxに静的アイテムとして保存され、を使用してGlobal.Repository、または同様の方法でヒットできると言えます。

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

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

何と言うの?

4

4 に答える 4

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アプリケーションと同様に、ユーザーオブジェクトをセッションに保存できます。ほとんどすべて(Response、Cache、Sessionなど)がまだ存在しますが、テスト用にモックできるように、それらの一部はSystem.Web.Abstractionsのクラスでラップされています。これらはすべて同じように動作しますが、従来の役割でそれらの一部を使用するべきではありません(たとえば、Response.Redirectを実行せず、リダイレクトを実行するRedirectToRouteResultなどのActionResultを返します)。

あなたの質問の背後にある理由については....

単一のデータベース接続にストレスをかけないでください。実装によっては、リクエストが相互にステップする可能性があるため、それは悪い考えでさえあるかもしれません。接続を開いて使用し、完了したら破棄/閉じます。

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

于 2009-05-27T12:50:32.977 に答える
3

セッションを使用する場合は、セッションクラスを用意することをお勧めします。これにより、コードで文字列名を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; }

    }
}
于 2009-05-27T13:13:32.773 に答える
2

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

于 2009-05-27T12:39:55.043 に答える
1

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

(彼のショッピングカートの実装に関するSteve SandersonのMVCブックを参照してください)

モデルバインダーを使用すると、HttpContextを持つcontrollerContextにアクセスできます。

于 2010-06-15T16:30:27.030 に答える