ASP.NET Core MVCでプロジェクトを複数のMVCプロジェクトに分割する方法

ASP.NET Core MVCでプロジェクトを複数のMVCプロジェクトに分割する方法

.NET Core MVCの開発において、肥大化しがちなMVCプロジェクトを機能ごとに切り分けて別のプロジェクトに分割する方法を紹介します。
執筆時点のASP.NET Coreのバージョンは2.1です。

MVCプロジェクトは規模が大きくなるとModel・View・Controllerがごちゃごちゃとしてきます。
そんな場合の解決方法を紹介します。

Areasによる解決

そこで第一に案内される手段がAreasです。
別途Areasのフォルダとルーティングを設定して、各機能のディレクトリ内でModel・View・Controllerを配置できます。
(詳細な方法は別途紹介します)

ただし、Areasの場合は階層構造を細かくして分かりやすくしている程度に過ぎません。
小~中規模で管理画面をAreasに分けるような使い方に適していると思います。

アクションパーツによる解決

次の方法として、公式の用語を使うと「アプリケーションパーツ」を使用します。
以下がリファレンスの説明ですが、正直もっと分かりやすく説明して欲しいところです。

MVC アプリはその機能をアプリケーション パーツから読み込みます。 たとえば、AssemblyPart クラスは、アセンブリでバックアップされるアプリケーション パーツを表します。 これらのクラスを使用して、コントローラー、ビュー コンポーネント、タグ ヘルパー、Razor コンパイル ソースなどの MBV 機能を検出して読み込むことができます。 ApplicationPartManager は、MVC アプリで使用できるアプリケーション パーツと機能プロバイダーの追跡を担当します。 MVC の構成時に Startup の ApplicationPartManager を操作できます。

つまりどういうこと?

MVCプロジェクトを2つ作成します。
1つ目は、通常のフロントとなるMVCプロジェクトです。
2つ目は、機能部分を別プロジェクトにすること目的としたMVCプロジェクトです。

この状態でFrontプロジェクトに「Home/Create(コントローラー/アクション)」を実行すると、
Frontプロジェクトに実装されたHome/Createの処理が実行されます。

次にFrontプロジェクトに「Func1/Create」を実行します。
すると、Frontプロジェクトに該当するコントローラー/アクションが無い場合、
参照関係があるアクションパーツ設定済みのMVCプロジェクトに対して、リクエストを伝播することが出来ます。

つまり、Frontプロジェクトに対して実行された「Func1/Create」は、Func1プロジェクトに実装されている処理が実行されます。

プロジェクトの作成と参照設定

MVCプロジェクトの作成はこちらを参照下さい。

プロジェクトの参照設定はこちらを参照下さい。

アクションパーツの設定

MVC.FrontプロジェクトルートのStartup.cs内に定義されている以下の箇所にピンクハイライト部分を記述します。
MVC.Func1のアセンブリをリクエストを伝播させるためのアクションパーツとしてセットします。

※GetTypeInfoはSystem.Refelectionをusingしていないとエラーになるのでご注意下さい。

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    var func1Assembly = typeof(MVC.Func1.Startup).GetTypeInfo().Assembly;
    services.AddMvc()
        .AddApplicationPart(func1Assembly)
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Viewの問題

これでMVC.Mainに定義されていないリクエストはMVC.Func1へ伝播されるようになりました。
ここで問題になるのがViewの存在です。
ViewはHTMLファイルなので、通常ではWebサーバーのディレクトリ構成に従う必要があります。
1つのWebアプリケーションなのにプロジェクトが複数に分かれている為、当然HTMLとなるViewファイルの配置が上手くいきません。
これまでの解決方法では、Webサーバー側でエイリアスを設定したりしていましたが、.NET Core 2.1から
追加された機能でViewsをコンパイルしてdllに出来るようになりました!

Viewsをdllにする場合の設定方法については、以下の記事を参考にして下さい。
.NET Core 2.1ではデフォルトではdllにしない設定となっている為、変更が必要です。

ViewsのDLL化設定方法

MVCプロジェクトのルートにある「プロジェクト名.csproj」を開き、PropertyGroup句にRazorCompileOnBuildとResolveRazorCompleToolsetを追加します。
その後、ビルドした結果プロジェクト名.Views.dllが生成されていれば成功です。

ProjectName.csproj

<PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RazorCompileOnBuild>true</RazorCompileOnBuild>
    <ResolvedRazorCompileToolset>RazorSdk</ResolvedRazorCompileToolset>
</PropertyGroup>

また、重要な点として現在の最新バージョン2.1の場合には、各プロジェクトのcsprojファイル内で.NetCoreのバージョンに明示的に2.1.1以上を指定する必要があります。
これを指定しないとViewsはDLL化されますが、DLL化されたViewを読み込みに行きません。

<PackageReference Include=”Microsoft.AspNetCore.App” Version=”2.1.1″ />

ASP.NET Coreカテゴリの最新記事