none
ViiewModelの初期化の実装について RRS feed

  • 質問

  • ASP.NET MVC でのViewModeのl実装についての質問です。

    コンストラクタでセッション値をメンバにセットするように実装しています。これは一般的・お作法的にどうなんでしょうか?

    個人的には、HttpContextクラスを使用することでASP.NET組み込みクラスに依存する実装であるということが気になっています。

    すべてのビューモデルクラスで共通に使用される値がセッションから取得する為、このような実装を行い、

    これを各ビューモデルが継承するという形をとっています。

        public class ATMViewModelBase
        {
            [Required(ErrorMessage = "口座番号は必須です")]
            [RegularExpression(@"\d{15}", ErrorMessage = "口座番号の形式が不正です。")]
            public string AccountNo { get; set; }
    
            public ATMViewModelBase()
            {
                AccountNo = HttpContext.Current.Session["accountno"] as string;
            }
        }

    2012年5月27日 14:50

回答

  • HttpContextを直に使うとテストがめんどくさくなるので、ATMSessionContextみたいなStaticクラスを作ってSessionの必要な情報を仲介する子を作ってあげるとか。

    ATMSessionContextがどこからでも参照できるなら、そもそも親クラスにAccountCdを持たないってのもありかと。


    • 回答としてマーク ham007 2012年5月29日 11:52
    2012年5月29日 1:57
  • 質問が良く理解できていませんが・・・

    > 個人的には、HttpContextクラスを使用することでASP.NET組み込み
    > クラスに依存する実装であるということが気になっています。

    気になる理由は何でしょうか? ASP.NET MVC では Session のよ
    うな ASP.NET 組み込みオブジェクトは使わないほうがよいという
    意味でしょうか?

    「プログラミング ASP.NET MVC」という本の受け売りですが、MVC
    は、従来の ASP.NET インフラストラクチャの上に成り立っており、
    Web Forms とはプログラミングモデルが異なるだけの、特殊な
    ASP.NET ランタイムと言えるそうです。つまり、MVC も、ASP.NET
    組み込みオブジェクトに依存しています。

    MVC でも、セッションをまたがってデータを維持する必要がある場
    合は、Session オブジェクトを使用するのが普通です(というより、
    それ以外に選択肢がない?)。なお、Session を使うことの問題点
    やメリットは ASP.NET Web Forms と同じで、MVC だからといって
    技術的な制限はないそうです。

    • 回答としてマーク ham007 2012年5月29日 13:13
    2012年5月29日 12:24
  • > ViewModelとして扱うクラスがHttpContextに依存するっていいのかな?

    コントローラのテスタビリティに影響があることを心配されているので
    しょうか? (ASP.NET ランタイムとの依存関係があると、Web サーバ
    内で実行しないとコントローラの完全なテストを実行できないというよ
    うな)

    でも、Session を使う以外選択肢がないならやむを得ないのではないでし
    ょうか。

    ASP.NET MVC では、静的クラスのモックを作成できるようにラッパークラ
    スが用意されていますので、そのような手段で対応されてはいかがでしょ
    う。

    • 回答としてマーク ham007 2012年5月30日 13:46
    2012年5月30日 13:17

すべての返信

  • HttpContextを直に使うとテストがめんどくさくなるので、ATMSessionContextみたいなStaticクラスを作ってSessionの必要な情報を仲介する子を作ってあげるとか。

    ATMSessionContextがどこからでも参照できるなら、そもそも親クラスにAccountCdを持たないってのもありかと。


    • 回答としてマーク ham007 2012年5月29日 11:52
    2012年5月29日 1:57
  • 返信有難うございます。

    >ATMSessionContextみたいなStaticクラスを作ってSessionの必要な情報を仲介する子を作ってあげるとか。
    なるほど。テストはHttpContextのモックを作成して対応していますが、お教えいただいた方法だとモックが要らなく、テストコードがわかりやすくなりますね。

    >ATMSessionContextがどこからでも参照できるなら、そもそも親クラスにAccountCdを持たないってのもありかと。
    これイイですね。使わせて貰います!

    2012年5月29日 11:51
  • 質問が良く理解できていませんが・・・

    > 個人的には、HttpContextクラスを使用することでASP.NET組み込み
    > クラスに依存する実装であるということが気になっています。

    気になる理由は何でしょうか? ASP.NET MVC では Session のよ
    うな ASP.NET 組み込みオブジェクトは使わないほうがよいという
    意味でしょうか?

    「プログラミング ASP.NET MVC」という本の受け売りですが、MVC
    は、従来の ASP.NET インフラストラクチャの上に成り立っており、
    Web Forms とはプログラミングモデルが異なるだけの、特殊な
    ASP.NET ランタイムと言えるそうです。つまり、MVC も、ASP.NET
    組み込みオブジェクトに依存しています。

    MVC でも、セッションをまたがってデータを維持する必要がある場
    合は、Session オブジェクトを使用するのが普通です(というより、
    それ以外に選択肢がない?)。なお、Session を使うことの問題点
    やメリットは ASP.NET Web Forms と同じで、MVC だからといって
    技術的な制限はないそうです。

    • 回答としてマーク ham007 2012年5月29日 13:13
    2012年5月29日 12:24
  • >質問が良く理解できていませんが・・・
    今まで見てきたサンプルコードでは、シンプルなクラスとしてViewModelが定義されているものしか見たことが無く、
    ViewModelとして扱うクラスがHttpContextに依存するっていいのかな?と思い質問させてもらいました。
    2012年5月29日 13:13
  • > ViewModelとして扱うクラスがHttpContextに依存するっていいのかな?

    コントローラのテスタビリティに影響があることを心配されているので
    しょうか? (ASP.NET ランタイムとの依存関係があると、Web サーバ
    内で実行しないとコントローラの完全なテストを実行できないというよ
    うな)

    でも、Session を使う以外選択肢がないならやむを得ないのではないでし
    ょうか。

    ASP.NET MVC では、静的クラスのモックを作成できるようにラッパークラ
    スが用意されていますので、そのような手段で対応されてはいかがでしょ
    う。

    • 回答としてマーク ham007 2012年5月30日 13:46
    2012年5月30日 13:17
  • >コントローラのテスタビリティに影響があることを心配されているのでしょうか?
    うまく言えないのですが、
    ViewModelは、ビューが描画するのに必要な情報を持つだけの軽量なクラスという認識でいます。
    これがSession情報へアクセスするということは、HTTPContextという大きなクラスに依存することになり、これはどうなんだろうか?と思ったのです。
    テストに関してはモッククラスで対応しています。

    >でも、Session を使う以外選択肢がないならやむを得ないのではないでしょうか。
    私もそう思いこういう実装にしました。が、良い実装であるとも思えず質問させてもらいました。

    >ASP.NET MVC では、静的クラスのモックを作成できるようにラッパークラスが用意されていますので、そのような手段で対応されてはいかがでしょう。
    ヒント有難うございます。調べてみます!


    2012年5月30日 13:46