5

現時点では、私はかなりひどいビューモデルを手に入れました。

クラスは次のようになります=>

 public class AccountActionsForm
    {
        public Reader Reader { get; set; }
        //something...
    }

問題は、Reader タイプがドメイン モデルに由来することです (SRP 違反)。

基本的に、私はデザインのヒントを探しています (つまり、ビューモデルを入力/出力に分割するのは良い考えですか?) ビューモデルを摩擦のない開発者に優しいものにする方法 (つまり、マッピングはコントローラーの基本クラスを使用して自動的に機能するはずです) ?

私は AutoMapper フレームワークを認識しており、おそらくそれを使用するつもりです。

もう一度言いますが、適切なビュー モデルを作成する際によくある落とし穴は何ですか? それをどのように構造化するのですか?複数のドメイン オブジェクトの入力が必要な場合、マッピングはどのように行われますか?


ビューが複数の集約ルートからのデータを必要とする場合について混乱しています。Library、Reader、BibliographicRecord などのエンティティを持つアプリを作成しています。

私の場合-ドメインレベルでは、これら3つのタイプすべてをグループ化することは意味がありませんLibraryReaderThatHasOrderedSomeBooksが、特定の図書館の特定の読者向けに注文された書籍に関するリストを表示するビューには、それらすべてが必要です。

そのため、その下にあるビューモデルを使用してビューを作成しOrderedBooksList、ビューモデルを作成しても問題ないようです。またはさらに良い-フラット化手法を活用し、などの小道具を持つビューモデル。OrderedBooksListModelLibraryOutputReaderOutputBibliographicRecordOutputOrderedBooksListModelReaderFirstNameLibraryName

しかし、複数の入力があるため、マッピングの問題が発生します。
1 つの集約ルートのみを開始するのは、もはや 1:1 の関係ではありません。
それは、私のドメイン モデルがちょっと間違っているということですか?

また、純粋に UI レイヤーにあるビュー モデル フィールド (つまり、チェックされたタブを示す列挙型) についてはどうでしょうか。

このような場合、これは誰もがすることですか?

 FooBarViewData fbvd = new FooBarViewData();
   fbvd.Foo = new Foo(){ A = "aaa"};
   fbvd.Bar = new Bar(){ B = "bbb"};
   return View(fbvd);

やりたくない=>

var fbvd = new FooBarViewData();
   fbvd.FooOutput =  _mapper.Map<Foo,FooOutput>(new Foo(){ A = "aaa"});
   fbvd.BarOutput = _mapper.Map<Bar,BarOutput>(new Bar(){ B = "bbb"});
   return View(fbvd);

書き込みが多いようです。:)


現時点でこれを読んでいます。そしてこれ


Ok。私はこの問題についてよく考えました。そうです-別の抽象化レイヤーを追加することは解決策のようです=>

代替テキスト

だから - 私の考えでは、これはすでに機能しています。

ジミー

4

3 に答える 3

4

これは、私たちが長い間代替案に苦労してきた後に私たちに気づいた1つの項目です。データのレンダリングは、データの受信とは異なります

ViewModelsを使用してデータをレンダリングしますが、フォームの投稿などを通じてデータを受信する場合、ViewModelsをModelBindingの概念に実際に適合させることができないことがすぐにわかりました。主な理由は、ブラウザへのラウンドトリップにはデータの損失が伴うことが多いためです。

例として、ViewModelsを使用していても、実際のドメインオブジェクトのデータに基づいていますが、ドメインオブジェクトのすべてのデータを公開しているわけではありません。これは、ブラウザによって投稿されたデータから、基になるドメインオブジェクトをすぐに再構築できない可能性があることを意味します。

代わりに、マッパーとリポジトリを使用して、投稿されたデータから完全なドメインオブジェクトを取得する必要があります。

これに気付く前は、投稿されたデータから完全なドメインオブジェクトまたはViewModelを再構築できるカスタムModelBinderの実装に苦労していましたが、現在は、データの受信方法をモデル化する個別のPostModelがあります。

抽象マッパーとサービスを使用して、PostModelをドメインオブジェクトにマップします。必要に応じて、ViewModelにマップします。

于 2010-01-07T13:36:14.657 に答える
4

これらすべてを定義するのは難しいですが、ここにあります。ビューが参照するものと、コントローラーが構築するものを区別したいと考えています。ビューには、フラット化された脳死状態の DTO のようなオブジェクトが表示されます。これをビューモデルと呼びます。

コントローラー側では、View Model を構築するために必要なものの豊富なグラフを構築します。これは、単一の集約ルートである場合もあれば、複数の集約ルートの構成である場合もあります。これらすべてが組み合わされて、プレゼンテーション モデルと呼ばれるものになります。プレゼンテーション モデルは単なる永続 (ドメイン) モデルである場合もありますが、まったく新しいオブジェクトである場合もあります。しかし、実際に私たちが見つけたのは、複合プレゼンテーション モデルを構築する必要がある場合、関連する動作を引き寄せる傾向があるということです。

あなたの例では、ViewFooBarModel と ViewFooBarViewModel (または ViewFooBarModelDto) を作成します。次に、コントローラで ViewFooBarModel について説明し、マッピングに依存して、この中間モデルから必要なものを AutoMapper で平坦化します。

于 2010-01-11T13:42:40.200 に答える
3

関連のないエンティティ (またはそのリポジトリ) をドメイン オブジェクトまたはサービスにグループ化することは意味がないかもしれませんが、それらをプレゼンテーション層にグループ化することは非常に理にかなっています。

特定のアプリケーションに特に適した方法でドメイン データを表すカスタム ViewModel を構築するのと同様に、必要に応じて組み合わせたカスタム プレゼンテーション層サービスも使用します。これらのサービスは、特定のビューをサポートするためだけに存在するため、よりアドホックです。

多くの場合、このサービスをインターフェースの背後に隠して、具体的な実装が、目的の結果を構成するために必要な、無関係な注入された Domain オブジェクトを自由に使用できるようにします。

于 2010-01-07T14:41:55.290 に答える