1

この質問には、実際にはより大きなアーキテクチャへの影響があり、これに関する意見や提案を歓迎します。

OOP に関して言えば、私は Martin Fowler 流の考え方です。UI でドメイン エンティティを直接レンダリングできるはずです。Car エンティティがあれば、それを Web ページにレンダリングできるはずです。ドメイン モデルは分野横断的な関心事であり、レイヤーではありません。ドメインモデルをレイヤーとして扱うと、ドメインモデルが貧血になります。私は OOP アーキテクチャの DTO を信じていません。

私にとってのビュー モデルは、ビューに必要なドメイン エンティティを構成する方法です。DTO ではありません。オートマッパーを使用するのは一般的なことのように思えますが、DTO のようなビュー モデルを使用する理由がわかりません。

そのため、メタデータ アプローチを使用して、ドメイン モデルにデータ アノテーションを配置し、エンティティのレンダリング方法と検証方法に関する UI 実装のヒントを提供します。私はよりリッチなドメインモデルが好きです。

MVC3 では、UI レイヤーに存在するリソース ファイルを使用して (具体的には Display data アノテーションを使用して) どのようにこれを達成できますか? これにはネイティブな実装がありますか、それとも自分で工夫する必要がありますか? それとも、私のアプローチのどこかで間違っていますか?

4

2 に答える 2

1

同意しません。

1つには、エンティティプロパティをWebページに表示する方法を指定するために使用する属性の一部は、System.ComponentModel.DataAnnotations名前空間ではなく、System.Web名前空間から取得されます。これらの属性をドメインモデルのプロパティに配置することにより、ドメインモデルはSystem.Webに依存します。たとえば、MVC3にフィールドをinput type="hidden"としてレンダリングするように指示する[HiddenInput]属性があります。これはSystem.CompoenentModel.DataAnnotationsにはありません。

第二に、リッチドメインモデルを作成するためにエンティティプロパティにデータアノテーション属性が必要だとは思いません。リッチドメインモデルは、知識をコンテキストにラップするクラスから生まれます。クライアントアプリケーションは、ドメインを使用するためにドメインについて何も知る必要はありません。ユビキタス言語を使用して知識を記述するクラス、メソッド、およびプロパティを備えたリッチドメインモデルを実現します。DataAnnotations属性は、ユビキタス言語のimoには適していません。そして、あなたのドメインは単なるあなたの実体以上のものです。リッチドメインモデルを構築するために使用できるファクトリ、サービス、およびその他のパタ​​ーンがあります。エンティティとメタデータのみを持つドメインは、私には貧血に聞こえます。

第三に、Webサイトでさまざまな方法でレンダリングする必要のあるエンティティがある場合があります。誰かが車を検索するとき、メーカー、モデル、年式、およびサムネイル写真だけを表示したい場合があります。誰かが検索結果をクリックしたときに、複数の写真やレビューなどを表示したい場合があります。エンティティのUIHint属性を使用して、車のレンダリング方法をWeb UIに指示する場合、さまざまなコンテキストで車をレンダリングするためのさまざまな戦略。

最後に、はい、オートマッパーはエンティティをビューモデルにDTOするのに非常に優れています。基本的に、特定のUIの懸念事項を対象として、ドメインから切断されたエンティティのコピーを作成できます。ここでは、HiddenInput属性とUIHint属性を使用して、MVC3にデータのレンダリング方法を指示しても安全です。

コメント1への回答

UIHintに関しては、MVC3 EditorTemplatesで特別な意味があるため、ここで説明しました。部分的なビューが入力の受信を伴う場合、ビューの構成はどのようになりますか?テキストフィールド、ドロップダウンリスト、および入力要素。これらは、一部の集計ルートのエンティティとそのプロパティに対応することがよくあります。したがって、データをカプセル化するには、エンティティの表現が必要になります。DTOは、深さのある集約ルートにすることもできます。スカラープロパティ(text / date / bool)、ナビゲーションプロパティ(ドロップダウンリスト)、およびコレクションプロパティ(ul / ol / table)を持つルートDTOを持つことができます。

集約ルート内の多くのエンティティに対応するビューモデルを作成し、EditorTemplatesを使用してそれらをビューとして実装します。別のEditorTemplateに切り替えたい場合は、UIHintをviewmodelプロパティに適用できます。したがって、「場所dtoをGoogleマップとしてレンダリングする」ように指示できます。Automapperは、ナビゲーションプロパティとコレクションプロパティを対応するビューモデルにマップし、ユーザーの必要に応じてドメインエンティティの複雑な表現を形成できます。

フラットdtoの意味を誤解した場合は、ご容赦ください。

コメント2への回答

ビューモデルdtoは、要件で必要な場合、(オートマッパーを使用して)一部のプロパティをフラット化/非正規化できます。たとえば、大学のエンティティについて考えてみます。多くの言語(翻訳)で多くの名前が付けられている可能性があり、UniversityNameエンティティを集約して示唆し、Universityには名前のコレクション(1..n)があります。これらの名前のうち、1はOfficialName / NativeNameを表し、別の名前はユーザーのCurrentUICultureへのTranslatedNameを表す場合があります。コレクション内の他のエンティティは、ユーザーが理解できない、煩わされる必要のないTranslatedNamesを表す場合があります。

コレクション内のこれら2つの名前のみに関心があるビューがある場合は、それらをビューモデルのファーストクラスのプロパティにプロモートできます。

public class UniversityViewModel
{
    public string OfficialName { get; set; }
    public string TranslatedName { get; set; }
    // ...other properties
}

これは、ビューモデルdtoに変換するときにエンティティの一部を非正規化することが理にかなっている場合です。ビューモデルがいかに貧血であるかに注目してください。コントローラーからビューへのデータ転送のためのベアコンテナーです。これは完全に問題なく、実際に推奨されています。

元の質問への回答

元の質問に答えるには、ドメインモデルとエンティティをレイヤー、より具体的には最下層と考えると役立ちます。アプリケーションのさまざまな懸念事項を他の懸念事項に依存していると考えると、階層化されたソフトウェアの方が理解しやすくなります。MVC3はプレゼンテーション/UIレイヤーであり、その下のレイヤーに依存します。そのうちの1つがドメインレイヤーです。

ドメインレイヤーからUIのリソースファイルにアクセスする場合は、反対方向に進みます。下位レイヤーを上位レイヤーに依存させることになります。ドメインライブラリがリソースのUIライブラリに依存し、UIライブラリがエンティティのドメインに依存している場合、循環依存になります。必要に応じてリフレクションを使用して達成できると思いますが、その場合はフレームワークと戦うことになります。その場合、MVCと.NETは一般的に最良の選択ではないかもしれません。

私は実際、リソースファイルを横断的関心事と考えています。私たちのアプリケーションにはi18nが散りばめられており、ドメインとUIの両方で同じ言語のテキストリソースが必要になることがよくあります。

エンティティにDisplay属性を設定しても問題はありません。ただし、リソースを使用する場合は、そのリソースをドメインレイヤーに配置するか、ドメインレイヤーに属していない場合は、下位レイヤーに配置します。そうすれば、ドメインとUIの両方からアクセスできます。

于 2011-12-18T18:20:34.053 に答える
0

そのため、リソース ファイルをドメイン モデルに配置し、カスタム HiddenFieldAttribute を追加して、ドメイン モデルで MVC アセンブリを参照する必要がないようにしました。

ビュー モデルが実際には DTO であり、ドメイン モデルをレイヤーとして構築する必要があるという点については、基本的に同意しません。このようにアプリケーションを設計すると、実際には価値のない抽象化が作成されると思います。ドメイン モデルが本当にレイヤーである場合、それにアクセスするための一連の論理インターフェイスを構築しますが、これは行いません。それは分野横断的な関心事です。

興味深い議論と、リソース ファイルをドメイン モデル アセンブリに配置しても問題ないことを提案してくれた Olivehour に感謝します。

于 2012-01-10T18:03:38.147 に答える