web-dev-qa-db-ja.com

サービスレイヤーとリポジトリレイヤーを備えたASP.NETMVC、インターフェイスはどこに定義する必要がありますか?

私は、リポジトリ層とサービス層を持つ.NETMVCアプリケーションのかなり単純な階層化アーキテクチャを決定しているところです。かなり明確で単純な例、特に www.asp.net と、ここでのいくつかの質問と回答を見つけましたが、少し単純で、小さなアプリケーションに適したものを探していますが、それはさまざまなプロジェクトを使用して、アイデアを広めます。上記にリンクした例では、Models名前空間のクラスとしてリポジトリとサービスがあります。それは私がそれを適切に説明することができるためにちょうど十分な明確な分離ではありません。

インターフェイスIRepositoryを実装するリポジトリ用の別のプロジェクトがあります。 IServiceを実装し、IRepository(コンストラクターインジェクション)を取得するサービス用の別個のプロジェクトがあります。サービスはIServiceを実装します。この例では、コントローラーがサービスをインスタンス化するだけで十分です。まだIoCコンテナーは必要ありません。これは、アーキテクチャのベストプラクティスを理解するための中間ステップであり、依存性の注入と、場合によってはより多くのレイヤーを含むように段階的に構築されるシーケンスの一部と考えてください。

問題は、IRepositoryとIServiceをどこで定義すればよいかということです。もちろん、サービスプロジェクトとリポジトリプロジェクトの両方がそれらを参照する必要があります。その場合、サービスプロジェクトとリポジトリプロジェクトの両方によって参照される別のプロジェクトで定義する必要があることは明らかです。もしそうなら、良い命名規則は何でしょうか? XXXXContractsのようなもの?

同様に、プレゼンテーション、サービス、およびリポジトリの各レイヤー間で渡されるデータモデルの場合、すべてのレイヤーによって参照されるXXXXModelsと呼ばれる個別のプロジェクトを持つことは許容されますか?サービス層とリポジトリ層の間で渡されるモデルが、サービス層とプレゼンテーション層の間で渡されるモデルと異なる場合があることを理解していますが、原則は同じです。

私はここで同様の質問に対する答えを見つけましたが、それらは私がここで概説したものよりも複雑なアーキテクチャを含む傾向があります。私は、データレイヤーを参照し、コントローラーにビジネスロジックを配置することで、上記の1〜2ステップと見なすことができる、2つのレイヤーの非常にシンプルでクリーンな図を作成したいと考えています。本格的なベストプラクティスに直行するための強力で有効な議論があることは知っていますが、誰もが一度にそのジャンプを行うのに適しているわけではありません。

17
Mark Farr

前書き

これも私が自問したことです。私がいつも持っている1つの燃える質問は、あなたの質問と似ています。

良い命名規則は何でしょうか?

名前はどのようにすればよいですか?それらはフォルダまたはプロジェクトに入れる必要がありますか?

周りを検索した後、答えはそれは実際には問題ではないということだと思います。重要なのは、ソリューションにいくつかの賢明なアーキテクチャがあり、 [〜#〜] solid [〜#〜] などの優れたプラクティスに従おうとすることです。

このトピックに関する私のASP.NETMVCヒーローは、 Jeffrey PalermoSteve Smith 、および Jimmy Bogard です。

タマネギのアーキテクチャ

ジェフリー・パレルモは古いアイデアの組み合わせについて話し合っていますが、それらをまとめて、視覚的に刺激的な名前を付けています オニオンアーキテクチャ (推奨読書)。ジェフリーは、物をどこに置くかという問題への良いアプローチを示しています。彼は、アプリケーションの中央(または上部)にコアがあると説明しています。このレイヤーは、IRepositoryIServiceなどのインターフェースを配置する場所です。

ほとんどすべてのインターフェースはコアに配置する必要があり、他のすべて(他のプロジェクト)はすべてコアを参照できます。このようにして、実装の詳細を知らなくても、すべてがアプリケーションの骨格構造を知ることができます。

Onion Architecture overview

UIレイヤーの参照をできるだけ少なくするようにしてください(理由の範囲内で)。私のアプリケーションの1つでは、UI(MVC)レイヤーはコアのみを参照しています。必要なものはすべて 依存性注入 で注入されます。

スティーブスミスは、オニオンアーキテクチャと同様のアイデアについて、 MVCソリューションのベストプラクティス:ソリューションの問題の解決策

私の解決策

私のMVCソリューションでは、次のような典型的な構造になっています。

  • MyProject.Core
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Tests

Coreには私のインターフェースが含まれています。通常、サービス、モデル、ドメイン、リポジトリなどのフォルダに分割されます。

Domainレイヤーはコアのみを参照し、私の実装が含まれています。これは、コアのドメイン抽象化のための多くの具体的なクラスを提供します。多くのビジネスロジック、処理、コマンド処理、マネージャークラス、具体的なサービスの実装などを扱います。私はそれをかなり内層だと考えているので、参照はできるだけ少なくしています。

DependencyInjectionレイヤーには、選択したDIパッケージ/フレームワークと実装の詳細が含まれています。私はそれを外層と考えています。 UIやインフラストラクチャに似ているので、多くを参照していても問題ありません。このレイヤーが別個のプロジェクトである必要はなく、多くの人がこれを行わないように指示します。それで大丈夫です;プロジェクトの複雑さに応じて機能することを実行します。私は自分のDIがそれ自身のものであることが好きです。それが非常に分離されていることの良いところは、DIフレームワークを別のフレームワークに置き換えることができ、問題がないことです。 DIプロジェクトを参照するレイヤーはありません。

Infrastructureレイヤーには、ロギング、電子メール、およびデータアクセスに関する情報が含まれています。選択した [〜#〜] orm [〜#〜] が含まれます。それはビジネスロジックのものではなく、UIのものでもありません。それは物事を成し遂げるための私の解決策の鉄道です。それは外層にありますが、コアのみを参照します。

Webレイヤーは私のMVCプロジェクトであり、コアのみを参照します。

複雑さと最終的な考え

私はここで同様の質問に対する答えを見つけましたが、それらは私がここで概説したものよりも複雑なアーキテクチャを含む傾向があります

それは良い点です。問題の複雑さを覚えておくことが重要です。しかし、優れたソリューションの実践に惑わされないでください。私のソリューションとOnionArchitectureは必ずしもそれほど複雑ではなく、ソリューションを実際に肥大化させることもありません。彼らは物事を別々に保つだけです。

Evolutionary Project Structure で、JimmyBogardは物事が複雑すぎることについて話します。私が言ったことが複雑すぎると思われる場合は、Jimmyのアドバイスに従って、すべてを1つのプロジェクト(UIレイヤー)に入れてください。それは大丈夫です-それがあなたに合っている限り。

私の解決策をアイデアとしてのみとらえることを忘れないでください。私のアプローチは、最高の賢者のアドバイスに従う試みですが、私はそれほど成功しただけだと確信しています。私はまだ改善することができます(そしてしなければなりません)。

54
Rowan Freeman