MVCアプリケーションのサービスレイヤーを作成しますか?


82

私が理解していることから、MVCは、コントローラーである「接着剤」を介して、クラス定義(モデル)をプレゼンテーション(ビュー)から分離します。コントローラは単一の責任を持つ必要があるため、テスト可能である必要があります。ViewModelsは、複数のエンティティからのデータをまとめ、ビューのコントローラーからのデータを「マッサージ」するために使用されます。

ビジネスロジックには実際には場所がないようです...したがって、サービスの別のレイヤーが適切だと思います。このレイヤーをどこに配置するか、またはサービスを構築する方法がわかりません。これは、多数の関数を含む「サービス」と呼ばれるクラスである必要がありますか?私はMVCに少し慣れていないので、読み物、サンプル、または一般的な新人の種類のヒントは素晴らしいでしょう。

回答:


126

ASP.NET MVCアプリケーションを開発するときは、通常、サービスレイヤーを使用します。これは、MartinFowlerがPatternsof Enterprise ApplicationArchitectureで説明しているサービスレイヤーパターンに似ています。それはあなたのビジネスロジックをカプセル化し、コントローラーをかなり薄くします。基本的に、コントローラーはサービスレイヤーを使用してドメインモデルを取得し、ドメインモデルをビューモデルに変換します。また、作業ユニットデザインパターンを使用してトランザクションを処理し、リポジトリデザインパターンを使用してデータアクセスレイヤーをカプセル化して、単体テストを容易にし、ORMを簡単に交換できるようにします。この図は、MVCアプリケーションで使用する一般的なレイヤーを示しています。

MVCアーキテクチャ

この図では、「サービスレイヤー」という用語を使用すると混乱するため、サービスレイヤーには「アプリケーションレイヤーまたはドメインレイヤー」というラベルが付けられています。彼らはこれがウェブサービスであると考える傾向があります。これは実際には、ASP.NET WebAPIやWCFなどのお気に入りのWebサービステクノロジやコントローラーで使用できるアセンブリです。

命名規則に関しては、私は通常、ドメインとそれに続くサービスを説明するものを使用します。たとえば、ユーザーメンバーシップを処理するサービスレイヤーがある場合、メンバーシップドメインをクエリおよび操作するためにコントローラーおよびWebサービスに必要なすべてのメソッドを持つMembershipServiceというクラスがあります。同じアプリケーションに複数のドメインがある場合があるため、複数のサービスレイヤーを使用できることに注意してください。ここでの私のポイントは、アプリケーション全体を処理する1つのモノリシックサービスを用意する必要がないということです。


7
この方法論を実装する良い例はありますか?
Animesh 2013年

@Animeshは、ネットの例、EF + Code FirstまたはDALのPOCOテンプレート、リポジトリとUnitOfWorkを生成するためのT4Scaffoldingを使用して作成する必要があります。サービスは、ビジネスロジックをカプセル化するDALとPOCOの間の調整です。次に、サービスレイヤーを呼び出して結果を表示するだけのASP.NET MVCコントローラーまたはWebApi(ASP.NET MVC)、または他のクライアントに公開する(ASP.NET WebApi)
riadh gomri 2013

2
リポジトリとUoWは不要ですね。少なくともあなたの例では、1つのデータベーステクノロジーだけを使用する必要がある場合(そしてそれはDDDではありません)。これが、EFがすでにUoWとリポジトリパターン自体を実装している理由です。
krypru 2017年

1
例とグラフィックが好きなので、ここについてはわかりませんが、オンラインのチュートリアルの多くは、リポジトリパターンを不必要に使用しています。それらは、利益なしに抽象化できるため、インターフェースを使用できるように抽象化します。
ジョニー2017年

驚くばかり !!!@kevin Junghansに感謝します。あなたの答えは、私が複雑なWebアプリケーションを設計するのに本当に役立ちました。1つの短い質問、マイクロサービスベースのWebアプリを開発している間、サービスクラスを実装する必要がありますか、それとも単にMVCクラスがその仕事をしますか。
codemilan 2017年

28

私のアドバイスは、「サービス」と呼ばれる別のクラスを作成することです。それらを異なるクラスライブラリ(または名前空間)プロジェクトに配置し、MVCフレームワークインフラストラクチャから独立させます。ある種の依存性注入も使用することをお勧めします(コンストラクター注入が最適です)。その場合、サービスクラスは次のようになります。

 public class MyService : IMyService
 {
     IFirstDependency _firstService;
     ISecondDependency _secondService;

     public MyService(IFirstDependency firstService, ISecondDependency secondService)
     {
     }

     public Result DoStuf(InputDTO)
     {
         // some important logic         
     }
 }

次に、コントローラーからこれらのサービスを利用します。完全な例については、こちらご覧ください。

リポジトリによると-ビジネスロジックはサービスレイヤーにカプセル化され、データベースはすでにORMフレームワークでカプセル化されているため、最新のORM(NHibernate、EntityFramework)を使用する場合は使用しないことをお勧めします。


4
リポジトリセクションをスキップしてORMに直接移動する場合の問題は、サービスクラスがORMコンテキストを直接取得することです。つまり、サービス内のすべてのクラスが、各サービスではなく、コンテキストにプルしたすべてのテーブルにアクセスできるようになります。必要なテーブルのみを操作するクラス。DbSetを各クラスのctorに渡し、DIで解決することでこれを回避できますが、問題が発生する可能性がありますか?
user441521 2016


10

「ビジネスロジックはモデルではなくサービスにあるべきだ」からの引用

MVP / MVC / MVVM / MV *アーキテクチャでは、サービスはまったく存在しません。または、そうであれば、この用語は、コントローラーまたはビューモデルに挿入できる一般的なオブジェクトを指すために使用されます。ビジネスロジックはモデルにあります。複雑な操作を調整するための「サービスオブジェクト」を作成する場合、それは実装の詳細と見なされます。悲しいことに、多くの人がこのようなMVCを実装していますが、モデル自体は何もしないため、アンチパターン(Anemic Domain Model)と見なされます。これは、UIの一連のプロパティにすぎません。

100行のコントローラー方式を採用し、それをすべてサービスに組み込むと、アーキテクチャが改善されると誤解する人もいます。実際にはそうではありません。おそらく不要な間接層をもう1つ追加するだけです。実際には、コントローラーはまだ作業を行っており、名前が不適切な「ヘルパー」オブジェクトを介して作業を行っています。貧血のドメインモデルを有用なものに変える方法の明確な例として、JimmyBogardのWickedDomainModelsプレゼンテーションを強くお勧めします。これには、公開しているモデルと、ビジネスコンテキストで実際に有効な操作を注意深く調べることが含まれます。


これが最良の答えです。選択されたものは、コントローラーで使用されるサービスにビジネスロジックを配置することを示していますが、ビジネスロジックはモデル上にある必要があります。
マテウスフェリペ

3

リポジトリパターンのようなものを探しているように聞こえます。あなたはここでそれについて読むことができます:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-application

ここでのこの回答も役立つ場合があります。

ASP.NETMVCに最適なリポジトリパターン


4
それは単なるリポジトリパターン以上のものです。サービスもデータアクセスに関するものです、私見だけではありません。
boj 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.