自分の今のプロジェクトで採用しているプロジェクト構成を紹介してみようと思います。何が正解とかはないと思いますが1つの例として参考になるかと。こういう情報が少ないので他の人はどうやってるのかすごい興味があります。オープンソースのものをたまに見ることはあるけどブログとかでってのはあまり見る機会ないですからね。変なとこありましたらツッコミなどよろしくお願いします!
前提
自分の場合はWebアプリだけでなくバックグラウンド処理サービスがあり、複数プロセスからDBアクセスしたいという要件がありました。
そういう要件がなくて単純なWebアプリの場合は1つのプロジェクトだけでもいいと思います。
その場合はフォルダ(名前空間)として分類することになります。ただフォルダだけだと本当にクラス同士が依存していないかコンパイラチェックではわかりません。なので依存関係がないことを確実にチェックしたい人は別プロジェクトにするといいですよ。
プロジェクト分けは、各プロセスが何に依存するかということ基準に決めます。
概要
VSで依存関係マップを生成してみました。7つのプロジェクトがありますね。この他にSiteToolというプロジェクトがありますが別slnになっているので見えません。矢印が参照を表すようですね。
プロジェクト名 | 種別 | 説明 |
---|---|---|
AppName.Core | ライブラリ | アプリ共通コード |
AppName.Models | ライブラリ | POCOモデルクラス |
AppName.DAL | ライブラリ | データアクセス関連コード(DB/Blob/File/Redis) |
AppName.Web | Web | Webアプリ |
AppName.Jobs | ライブラリ | バックグラウンド処理のinterface定義 |
AppName.Sites | ライブラリ | バックグラウンド処理実装 |
AppName.Hangfire | コンソール | バックグラウンド処理用のWindowsサービス |
AppName.SiteTool | WinForms | バックグラウンド処理の開発用GUIツール |
では順に説明していきます。
AppName.Core
Coreにはアプリ共通のクラスを格納します。余計な依存関係はありません。クリーンです。Jsonくらいあってもいいかも。僕のプロジェクトにはアプリ例外クラス、エラーコード定義、ユーティリティ拡張メソッドなどがあります。小さいです。
もしアプリ共通で使うけど依存DLLが必要な場合は、こう考えます。
- 将来も含めてすべてのプロセスで必要になるなら追加する。
- そうでないなら別プロジェクトにする。
依存関係:
なし
AppName.Models
ModelsにはPOCOのモデルクラス「だけ」を格納します。DB関係ないモデルクラスも入ってもいいですが、こちらも余計な依存関係は持ち込まないようにします。
依存関係:
AppName.Core
AppName.DAL
DALにはデータアクセス関連のコードを格納します。ApplicationDbContext、DbMigrationsConfiguration、Redis、BlobStorageなどですね。接続文字列などは各プロセスプロジェクトのWeb.config(App.config)で定義したものを参照します。
依存関係:
AppName.Core
AppName.Models
AppName.Web
Webアプリ本体ですね。フロント側の処理になります。ポイントはAppName.Hangfireに依存していないことです。バックグラウンド処理のジョブを実行する場合はAppName.Jobsで定義したinterfaceでHangfireジョブをキックします。
依存関係:
AppName.Core
AppName.Models
AppName.DAL
AppName.Jobs
AppName.Jobs
バックグラウンドジョブのinterface定義のみを含みます。AppName.Webから依存関係を取り除くために必要になります。Hangfireのジョブクラスをinterfaceにすることで依存関係を取り除くことができます。
依存関係:
なし
AppName.Sites
バックグラウンド処理をここで実装します。Blobを事前にローカルにDLしたりして、今のところDALには依存せずに済んでいますね。
依存関係:
AppName.Core
AppName.Models
AppName.Hangfire
バックグラウンド処理用のWindowsサービスです。デバッグ用にコンソールでも動作するようになっています。運用時にはこいつを複数個起動します。モジュール更新時はプロセス停止が必要なので複数個必要です。
依存関係:
AppName.Core
AppName.Models
AppName.DAL
AppName.Jobs
AppName.Sites
AppName.SiteTool
バックグラウンド処理(AppName.Sites)を簡単に呼び出すために作った開発用のGUIツールです。Hangfire経由ではなくボタンクリックでジョブを実行できます。
依存関係:
AppName.Core
AppName.Models
AppName.Sites
まとめ
いかがでしたでしょうか。後半疲れて尻すぼみになりました。。
ぜひみなさんのプロジェクト構成も晒してみてください!