2009-09-26 9 views
11

私は、NerddinnerとContactManagerのようなよりシンプルなアプリケーションだけでなく、Kiggのようなもっと複雑なアプリケーションも見てきました。私は単純なものを理解していますが、今はより複雑なものを理解したいと思います。私のMVCを次のレベルに引き上げる:DIと作業単位

通常、単純なアプリケーションの場合、LINQtoSQLまたはEntity Frameworkの上に、リポジトリクラスとインターフェイス(取得できるように疎結合)があります。リポジトリは、必要なデータ操作を行うためにコントローラから呼び出されます。

私はKiggまたはOxiteのような、より複雑なアプリケーションを調べるときに私が見る一つの一般的なパターンは、(私はここに、表面に傷をつけていますが、私はどこかに起動する必要があります)の導入である:

  • IOC DI(Kiggの中ケースここで働い

のユニティ)

  • のWebリクエスト生涯マネージャ
  • ユニットが私の質問です:

    本当に疎結合されたアプリケーションを実際に使用するには、Unityのようなものを使用する必要があることを理解しています。しかし、Unityにミックスを導入した瞬間も、Web Request Lifetime Managerを導入する必要があります。何故ですか? NerddinnerのようなサンプルアプリケーションにWeb Request Lifetime Managerがないのはなぜですか?それは正確に何をしますか?ユニティ特有のものですか?

    第2のパターンは、作業単位(Unit of Work)の導入です。再度、同じ質問:なぜNerddinnerまたはContactManagerはUnit of Workを使用しないのですか?代わりに、これらのアプリケーションは、Linq2SqlまたはEntity Framework上のリポジトリクラスを使用してデータ操作を行います。作業部会の兆候はありません。それは正確に何であり、なぜそれを使うべきなのでしょうか?

    おかげ以下

    はDinnersControllerレベルでNerddinerにDIの例である:

    public DinnersController() 
         : this(new DinnerRepository()) { 
        } 
    
        public DinnersController(IDinnerRepository repository) { 
         dinnerRepository = repository; 
        } 
    

    は、だから私は右のために最初のコンストラクタのコントローラはDinnerRepositoryし、それを「所有」することを前提としていますしたがって、コントローラが宣言されて以来、コントローラの寿命に依存しますか?

  • 答えて

    3

    Linq-to-SQLは直接使用され、コントローラはデータコンテキストへの参照を所有します。これは通常、コントローラー内のプライベートな参照であり、構造の一部として作成されます。それは1つの場所にあるので、生涯管理の必要はありません。

    ただし、IoCコンテナを使用すると、データリポジトリがコントローラ外に作成されます。あなたのためにそれを作成するIoCコンテナは、作成されたオブジェクトをどのくらい、そしてどれくらい長く使うのか分からないので、生涯戦略が導入されます。

    たとえば、データコンテキスト(リポジトリ)は、通常、Webリクエストの開始時に作成され、最後に破棄されます。ただし、外部Webサービスやスタティックマッパー(たとえばロガー)で動作するコンポーネントの場合は、毎回作成する必要はありません。だから、あなたはそれらを一度作成するように言いたいかもしれません(つまり、singletoneのライフスタイル)。

    これはすべて、IoCコンテナ(Unityのような)が多くの状況を処理するように設計されており、特定のニーズを知らないためです。例えば、いくつかのアプリケーションは、NHibernate(またはEntity Frameworkが多分)がいくつかのページ/ Webリクエスト中に持続するかもしれないところの "会話"トランザクションを使用します。 IoCコンテナを使用すると、ニーズに合わせてオブジェクトのライフタイムを調整することができます。しかし、これは価格になると言われています - あらかじめ定義された単一の戦略がないので、自分で選択する必要があります。

    NerdDinnerとその他のアプリケーションが高度なテクニックを使用しないのは、他のライブラリの高度な使用法ではなく、MVC機能を示すためです。私は、IoCコンテナの高度な機能を実証するために書かれた記事を覚えています。この記事は、懸念の分離のような承認されたデザインパターンを破ったものですが、デザインパターンが記事の目標ではないため、シンプルなMVCデモンストレーションアプリケーションと同じですが、MVC初心者のあなたがIoCの迷路で失われることを望んでいません。

    そして、私はデザインの参考例としてOxiteを見てお勧めしません: http://codebetter.com/blogs/karlseguin/archive/2008/12/15/oxite-oh-dear-lord-why.aspx http://ayende.com/Blog/archive/2008/12/19/oxite-open-exchangable-informative-troubled-engine.aspx

    +0

    ありがとうございました!それが助けになりました。私は質問を編集しました。これはコントローラがリポジトリ/データコンテキストへの参照を所有していると言ったときの意味ですか? – Thomas

    +0

    正確ではありません。 NerdDinnerでは、ユニットテストを容易にするためにIDinnerRepositoryを受け入れる追加のコンストラクタを使用します。しかし、それはまだコントローラ(パラメータのないコンストラクタ)またはリポジトリオブジェクトを作成して所有するテストのいずれかです。彼らは死んでも、リポジトリの他のユーザもいません。生涯は簡単です。ところで、そのような技術は悪いです。あなたはそれについてもっとここで読むことができます:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/03/how-not-to-do-dependency-injection-in-nerddinner.aspx(同様に「貧しい人のIoC」の場合はgoogle)。 – queen3

    +0

    ジミー・ボガードの「貧しい男のIoC」の荒々しい例であるという議論は、ここでは非常に良いです。コメントも良いです。間違いなく読む価値がある。 –

    0

    ほとんどすべてのDIコンテナが生命の概念に触れるわけではありませんが、私は信じています。関係するシナリオに応じて、コンテナが登録されたコンポーネントの同じインスタンスを常に返すようにし、別のコンポーネントの場合は常に新しいインスタンスを返すようにすることができます。ほとんどのコンテナでは、特定のコンテキスト内で同じインスタンスを返すように指定することもできます。

    私はよく知らない(これまではWindsorとAutofacを使用していましたが)単一のWeb要求の存続期間中に同じインスタンスがコンテナによって提供されるライフタイム戦略の実装であるとWebの要求ライフタイムマネージャが疑わしい場合。ウィンザーのようなコンテナでも同様の戦略を見つけることができます。

    最後に、あなたはUnit of Workを指していると思います。作業単位は、本質的には、1つの基本的なビジネス・トランザクションとして成功または失敗するアクションのグループです。より正式な説明については、Martin Fowlerのdefinitionをご覧ください。これは、ドメイン駆動型設計のコンテキストでより多くの人気を集めた概念です。作業単位は、そのようなトランザクションで適用される変更を追跡し、正しいときには、1つのACIDトランザクションでこれらの変更をコミットします。例えばNHibernateにおいて。セッションはLinq2SQLではコンテキストであり、作業単位、より具体的には変更トラッキングの概念をサポートしています...

    関連する問題