3

私はほとんどCRUDアプリであるasp.net-mvcサイトを持っていますが、webviewの外でいくつかの追加と更新も行っています(スプレッドシートからのアップロードなど)。 この記事に基づいて、MVC プロジェクトの外部のロジックを別の共有プロジェクトにできるだけ多く取得しようとしています。これにより、すべてのシナリオで同じコードを再利用でき、バインドされている「読み取り」ビューモデルを分離して分離しようとしています。フォーム投稿でサーバーに投稿されているものを表す「編集」ビューモデルから表示するための UI。

他のソリューションと共有されているソリューション (domainobjects、importexport など) に多数のプロジェクトがあり、MVC プロジェクトには MVC プロジェクトに次のディレクトリがあります。

  • コントローラー
  • ビュー
  • ビューモデル
  • スクリプト
  • EditViewModels

ViewModels フォルダーは、ビューにバインドしているオブジェクトを表します (通常、以下を含むコンテナー オブジェクト)。

  • ドメイン オブジェクトと
  • UI ドロップダウンなどを設定するための SelectListItem の IEnumerable の束

このようなもの:

 public class OrderViewModel
 {
       public Order MyOrder {get;set;}
       public IEnumerable<SelectListItem> OrderTypes {get;set;}
       public IEnumerable<SelectListItem> Sizes {get;set;}
 }

私の EditViewModels フォルダーは、フォームからサーバーに投稿しているオブジェクトを表しているため、通常は、次のようにデータベースを追加または更新する前に、ドメイン オブジェクトに入力するプリミティブのみを含む単純なフラット オブジェクトです。

public class OrderEditViewModel
{
      public int Id {get;set;}
      public int OrderTypeId {get;set;}
      public int SizeId {get;set;}
}

私の主な質問は、通常は次のように見えるコントローラークラスにメソッドがある場合です(簡略化):

  public ActionResult Update(OrderEditViewModel order)
  {
         var existingOrder = _repository.GetOrder(order.Id);
         existingOrder.Name = order.Name;
         existingOrder.Size = _repository.GetSize(order.SizeId);
         existingOrder.Price = order.Price;
         _repository.Save(existingOrder);
         return Json( Result = "Success");
  }

MVC プロジェクトの外部でできるだけ多くのコードを取得する方法を見つけようとしていますが、MVC プロジェクトの外部の EditViewModel 内のすべてのクラスを移動して、それらのオブジェクトを再利用できるようにする必要があります。

これらの「Post」データ構造を MVC プロジェクトの外部でクラス化することに何か問題があると思いますか。「ビューモデル」クラスを考えると、それをビューから遠ざけるのは間違っているように感じますが、MVC プロジェクトの外でこのコードを共有する方法は他にありません。ここの「viewModel」の名前が間違っているのではないでしょうか?

4

8 に答える 8

6

ビュー モデルはビューに固有のものであり、他のものに関連するものであってはなりません。それらには、選択リストなど、他に気にする必要のないものが含まれています。そのため、UI にとどまる必要があります。

この記事は、ビジネス ロジックが UI (または少なくとも UI モデル、つまりビュー モデル) に依存する状況を作り出しているように見えますが、それは間違ったアプローチだと思います。UI は、UI が何であるかをビジネス ロジックが認識しなくても、ビジネス ロジックを使用できる必要があります。これは、Web サイト、ファット クライアント、モバイル クライアント、Web サービスなどである可能性があります。このロジックをビュー モデルに依存させることで、Web ベースではない将来のサービスがそれらに依存するようになります。

ただし、これは単純な CRUD アプリです。単純な CRUD アプリでは、追加のエンジニアリング作業を行う価値がないため、多くの場合、多くのショートカットを使用できます。通常、View Model で直接ドメイン オブジェクトをビューに渡すことはありません。しかし、この場合はおそらく最良の選択です。

ただし、それを「正しく」行いたい場合は、関心をさらに分離する必要があります。ドメイン層と UI 層をさらに分離する必要があります。個別のビュー モデルとドメイン モデルを作成し、それらの間をマッピングします。これにより、ビジネス層が UI について何も知ることができなくなります。

おそらく、ロジックを処理するサービス層を作成します。例えば:

_orderService.UpdateOrder(order.Id, order.Name, order.Price);
于 2013-08-04T21:31:33.460 に答える
1

2 つのアセンブリで 4 つの「レイヤー」を使用します

3 つの名前空間を持つ {application}.app アセンブリであり、通常のクラス ライブラリ プロジェクトです。

1) ドメイン モデルの {application}.model

2) リポジトリ パターンを使用するデータの {application}.data

3) すべてのビジネス ロジックの {application}.services

{application}.UI の WebUI アセンブリ。これは MVC プロジェクトです。

コントローラはサービスのみを呼び出し、サービスはリポジトリを介してデータを取得および更新します。

アプリが実行する必要があるすべての操作には、サービス API があります。つまり、

OrderServices.Update (既存の注文)

OrderServices.Approve (既存の注文)

サービスレイヤーはドメインモデルのみを認識し、コントローラーはサービスから取得したドメインモデルを使用してビューモデルを組み立ててビューに送信し、ビューから取得したビューモデルを使用してドメインモデルを準備して適切なサービスに送信します。

このようにして、最終的に {application}.WebAPI または同じ {application}.app アセンブリを使用するものを作成して、すべてのビジネス ロジックを再利用し、ビューモデルを所属する場所 (WebUI プロジェクト) に保持できます。

お役に立てれば。

よろしくお願いします。

于 2013-08-11T04:04:24.957 に答える
0

プロジェクトのサービス アーキテクチャを使用できます。ここでは、すべての関数と db クエリがこのファイルにあり、このコードを追加するだけで使用できます。

 IOrderService<Order> service = new OrderEntityService();

そしてそれを次のように使用します

service.Create(Order) or service.Update();
于 2013-08-04T16:08:53.423 に答える
0

まあ、私はあなたの状況を理解しており、@MystereMan が示唆するように、DDD (ドメイン駆動設計) ソリューションにも傾向があります。

「モデル」を3つのカテゴリに分けるアプローチがあります。

  1. ViewModels: UI にコンテンツ データを表示するために必要なすべての情報を持っています。
  2. RequestModels: データの送信、ポスト/取得などに必要なすべての情報を持っています。)
  3. AutoBindModels: MVC バインディング モデル (Cookie、セッションなど) に注入されたすべての情報を保持します。

そして最も重要なことは、私が DTO/POCO として使用するすべてのクラスについて、実際にはプロパティ/計算されたプロパティだけの UI 依存コードがなく、UI プロジェクトによって参照される他のプロジェクトで簡単に使用できることです。

また、ASP.MVC プロジェクトの外部でサービスとして機能するコントローラー クラスを作成し、それを拡張または MVC コントローラーに挿入することもできます。

それが役に立てば幸い...

于 2013-08-13T15:38:21.880 に答える
0

(Edit)ViewModels オブジェクトを再利用することはありません (これは完全に正しいわけではありません。Create と Update の間で 1 つの EditViewModel を共有することがよくありますが、常にではありません)。

特定のビュー用に ViewModel を設計しています。したがって、UI が変更されたときに ViewModels を妥協する必要はありません (常に変更されます)。

同一であっても、2 つの異なる ViewModel を作成する限り、これを使用します。共有ViewModelのリファクタリングが完了しました..

私はあなたの質問に「はい」と答えます。

それが役に立てば幸い。

于 2013-08-13T20:06:21.100 に答える
-1

OrderEditViewModel両方ともOrderViewModel「ViewModels」の終わりです。IMO、同じ「ViewModels」フォルダーであっても、同じプロジェクトに一緒に残る場合があります。ただし、「EditViewModels」の ViewModels の下にサブフォルダーを作成することはできます。

コントローラーのアクションをクリーンアップ/整理したい場合は、AutoMapperまたはValueInjecterを使用することをお勧めします。ドメイン エンティティとビュー モデルを手動でマッピングしています。それは面倒な仕事です。AutoMapper を使用すると、次のようなことができます。

var customerInfo = Mapper.Map<CustomerViewModel, CustomerInfo>(customerViewModel);
于 2013-08-04T17:25:32.197 に答える