自分の今のプロジェクトで採用しているプロジェクト構成を紹介してみようと思います。何が正解とかはないと思いますが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が必要な場合は、こう考えます。

  1. 将来も含めてすべてのプロセスで必要になるなら追加する。
  2. そうでないなら別プロジェクトにする。

依存関係:

なし

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

まとめ

いかがでしたでしょうか。後半疲れて尻すぼみになりました。。

ぜひみなさんのプロジェクト構成も晒してみてください!