4

ソリューションに設計上の欠陥があるかどうか疑問に思っています。これが私が持っているものです:

  • Entities=>純粋なポコ。参照:なし。
  • Data=>データアクセス。参照:Entities
  • Service=>ビジネスロジック。参照:EntitiesおよびData
    • マネージャークラス。
    • ViewModels。
  • WebApp=>UI。参照:EntitiesおよびService

WebAppUIとしてのASP.NETMVCプロジェクト、Entities純粋なPOCOを保持するための参照のないプロジェクト。DataデータベースにアクセスしService、ビジネスロジック(私のマネージャークラスがある場所)にアクセスします。

基本的に、私はManagerすべてのエンティティのクラスを定義しました。たとえば、Messageエンティティのリストに関連するエンティティがありRecipientます。データ層を使用したCRUD操作と論理結果の両方を担当するクラスMessageManagerとクラスがあります(例)RecipientManagerpublic List<Message> GetAllMessagesWithPermissionForUser(User user, Permission permission)

私のMVCプロジェクトでは、サービスレイヤーでいくつかのViewModelクラスを定義して、ビューの特定のビデオモデルを生成しました。ビューモデルはManagerクラスを使用しているため、サービスクラスで定義しました。たとえばMessageOperationVM、プロパティを持つビューモデルがありPermittedBoxesToSendます。このプロパティは、私のBoxManagerクラスを使用して、指定されたメッセージで許可されているすべてのボックスを取得します。

// Initialized by Catsle Windsor.
public BoxManager BoxManager {get; set;}

public List<Box> PermittedBoxesToSend 
{
    if(this._premittedBoxesToSend != null)
    {
        this._permittedBoxesToSend = BoxManager.GetPermittedBoxesToSend(this.Message);
    }
}
  • Viewmodelsでマネージャークラスを使用することが良い設計であるかどうかはわかりません。DIを設定するためのコンストラクター/プロパティセッターとして定義しましたが。プロパティを定義する代わりに、ビューモデルのプロパティをコントローラーに入力して、ビューモデルのマネージャークラスを削除する必要がありますか?

    public ActionResult ShowNewMessageDialog()
    { 
        var messageVM = new MessageOperationVM() { new Message() };
        messageVM = this.BoxManager.GetPermittedBoxesToSend();
    }
    
  • エンティティごとにマネージャークラスを使用すると、メンテナンスが難しくなるようです。BaseManager(それらはすべて、共通の操作を共有 するクラスから派生していますが)

  • 上記のデザインで言及する価値のある再考はありますか?

ありがとうございました。

更新
eulerfxの回答に基づく:
あなたの回答で私が抱えている問題は次のとおりです。ViewModelを構築するには、いくつかのサービスレイヤーのメソッドを呼び出す必要があります。そのため、pocoエンティティだけに基づいてViewModelを構築することはできません。これらのパーツもコントローラーで作成することをお勧めしますか?:

public ActionResult ShowNewMessageDialog()
{
    var message = this.messageRepository.GetMessage();
    var messageVM = new MessageViewModel(message);
    messageVM.CustomProperty = this.messageManager.CallSomeMethod(message);
    return View(messageVM);
}
4

2 に答える 2

9

ビューモデルからサービスへの参照は設計上の欠陥であると考えます。ビューモデルは、ビューとのバインドを目的としたフラットでシンプルなDTOである必要があります。それらはDIコンテナグラフの一部であってはなりません。それは物事を複雑にし、コードについての推論をより困難にするからです。使用している用語の受け入れられる定義は次のとおりです。

  • あなたが説明したように、エンティティはエンティティです。それらは単純なPOCOクラスです。
  • 「データ」と呼ばれるのはリポジトリパターンです。リポジトリは、基盤となるデータベース内のエンティティへのアクセスと永続性を提供します。
  • サービスは過負荷の用語ですが、通常、ドメインをカプセル化してAPIとして他のアプリケーション層に公開するために使用されます。サービスはリポジトリを参照できます。これらのタイプのサービスについて、アプリケーションサービスと呼ばれるDDDのコンテキストでブログ投稿を書きました
  • ビューモデルは、プレゼンテーション層またはWebUIの一部です。そのため、それらはMVCコントローラーによって構築され、ビューに渡されます。コントローラは、アプリケーションサービスまたはリポジトリから直接取得したデータを使用してビューモデルを構築します。ビューモデルには、サービスまたはリポジトリから返されたエンティティを受け入れるコンストラクターを含めることができます。

コードは次のようになります。

/// Domain model class that lives in domain/business layer project
public class Message
{
  // properties and behavior go here
}

// View model class that lives in the ASP.NET project
public class MessageViewModel
{
  public MessageViewModel() { }
  public MessageViewModel(Message message)
  {
    // construct the view model based on the provided entity
  }
  // properties specific to the view go here
} 


// ASP.NET MVC controller.
public class MessagesController : Controller
{
 // this repository should be injected by DI container.
 readonly IMessageRepository messageRepository;

 public ActionResult ShowNewMessageDialog()
 {
   var message = this.messageRepository.GetMessage();
   return View(new MessageViewModel(message));
 }
}
于 2012-04-25T05:08:14.917 に答える
1

Managerクラスの代わりに、Visitorデザインパターンを使用してEntitiesDataクラスを操作することを検討してください。

ManagerまたはVisitorクラスが、ビューコードでのみ使用する必要がないように定義されている場合は、問題にはなりません。ただし、ビューでのみ使用でき、他のビューなどでは、EntitiesおよびDataクラスへのアクセスを再定義するか、より多くの/重複するコードを作成する必要がある場合は、問題があります。

于 2012-04-24T07:43:37.107 に答える