コントローラー、ビュー、Razor Pages などをアプリケーション パーツと共有する

作成者: Rick Anderson

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

"アプリケーション パーツ" は、アプリのリソースを抽象化したものです。 ASP.NET Core は、アプリケーション パーツを利用して、コントローラー、ビュー コンポーネント、タグ ヘルパー、Razor Pages、Razor コンパイル ソースなどを検出できます。 AssemblyPart はアプリケーション パーツです。 AssemblyPart はアセンブリ参照をカプセル化して、型とコンパイル参照を公開します。

"機能プロバイダー" は、アプリケーション パーツと連携し、ASP.NET Core アプリの機能を組み込みます。 アプリケーション パーツの主なユース ケースは、アセンブリから ASP.NET Core 機能を検出 (または読み込みを回避) するようにアプリを構成することです。 たとえば、複数のアプリで共通の機能を共有したいとします。 アプリケーション パーツを使用すると、コントローラー、ビュー、Razor Pages、Razor コンパイル ソース、タグ ヘルパーなどを含むアセンブリ (DLL) を複数のアプリと共有できます。 複数のプロジェクトでコードを複製するよりもアセンブリの共有をお勧めします。

ASP.NET Core アプリは ApplicationPart から機能を読み込みます。 AssemblyPart クラスは、アセンブリでバックアップされるアプリケーション パーツを表します。

ASP.NET Core 機能の読み込み

Microsoft.AspNetCore.Mvc.ApplicationParts および AssemblyPart クラスを使用し、ASP.NET Core 機能 (コントローラー、ビュー コンポーネントなど) を検出して読み込みます。 ApplicationPartManager は、使用可能なアプリケーション パーツと機能プロバイダーを追跡します。 ApplicationPartManagerStartup.ConfigureServices で構成されます。

// Requires using System.Reflection;
public void ConfigureServices(IServiceCollection services)
{
    var assembly = typeof(MySharedController).Assembly;
    services.AddControllersWithViews()
        .AddApplicationPart(assembly)
        .AddRazorRuntimeCompilation();

    services.Configure<MvcRazorRuntimeCompilationOptions>(options => 
    { options.FileProviders.Add(new EmbeddedFileProvider(assembly)); });
}

次のコードは、AssemblyPart を使用して ApplicationPartManager を構成する別の方法を示しています。

// Requires using System.Reflection;
// Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
public void ConfigureServices(IServiceCollection services)
{
    var assembly = typeof(MySharedController).Assembly;
    // This creates an AssemblyPart, but does not create any related parts for items such as views.
    var part = new AssemblyPart(assembly);
    services.AddControllersWithViews()
        .ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part));
}

上記 2 つのコード サンプルでは、アセンブリから SharedController が読み込まれます。 SharedController は、アプリのプロジェクト内にありません。 WebAppParts ソリューションのサンプル ダウンロードを参照してください。

ビューを含める

アセンブリにビューを含めるには、Razor クラス ライブラリを使用します。

リソースの読み込みを防ぐ

アプリケーション パーツを使用して、特定のアセンブリまたは場所にあるソースの読み込みを "回避" することができます。 Microsoft.AspNetCore.Mvc.ApplicationParts コレクションのメンバーを追加または削除して、リソースを非表示にしたり使用可能にしたりします。 ApplicationParts コレクションでのエントリの順序は重要ではありません。 ApplicationPartManager を構成してから、コンテナーでサービスを構成するために使用します。 たとえば、AddControllersAsServices を呼び出す前に ApplicationPartManager を構成します。 リソースを削除するには、ApplicationParts コレクションに対して Remove を呼び出します。

ApplicationPartManager には次のパーツが含まれています。

  • アプリのアセンブリおよび依存アセンブリ。
  • Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyPart
  • Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.Razor

機能プロバイダー

アプリケーション機能プロバイダーはアプリケーション パーツを調べ、これらのパーツの機能を提供します。 次の ASP.NET Core 機能には組み込みの機能プロバイダーがあります。

機能プロバイダーは IApplicationFeatureProvider<TFeature> から継承されます。ここで T は機能の種類です。 機能プロバイダーは、前述の機能の種類のいずれについても実装できます。 ApplicationPartManager.FeatureProviders の機能プロバイダーの順序が実行時の動作に影響することがあります。 後から追加されたプロバイダーは、前に追加されたプロバイダーによって行われたアクションに対応できます。

使用可能な機能の表示

アプリで使用できる機能を列挙するには、依存関係の挿入によって ApplicationPartManager を要求します。

using AppPartsSample.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.ViewComponents;

namespace AppPartsSample.Controllers
{
    public class FeaturesController : Controller
    {
        private readonly ApplicationPartManager _partManager;

        public FeaturesController(ApplicationPartManager partManager)
        {
            _partManager = partManager;
        }

        public IActionResult Index()
        {
            var viewModel = new FeaturesViewModel();

            var controllerFeature = new ControllerFeature();
            _partManager.PopulateFeature(controllerFeature);
            viewModel.Controllers = controllerFeature.Controllers.ToList();

            var tagHelperFeature = new TagHelperFeature();
            _partManager.PopulateFeature(tagHelperFeature);
            viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();

            var viewComponentFeature = new ViewComponentFeature();
            _partManager.PopulateFeature(viewComponentFeature);
            viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();

            return View(viewModel);
        }
    }
}

ダウンロード サンプルでは、前のコードを使用してアプリの機能を表示します。

Controllers:
    - FeaturesController
    - HomeController
    - HelloController
    - GenericController`1
    - GenericController`1
Tag Helpers:
    - PrerenderTagHelper
    - AnchorTagHelper
    - CacheTagHelper
    - DistributedCacheTagHelper
    - EnvironmentTagHelper
    - Additional Tag Helpers omitted for brevity.
View Components:
    - SampleViewComponent

アプリケーション パーツでの検出

アプリケーション パーツを使用した開発では、HTTP 404 エラーが発生することは珍しくありません。 通常、これらのエラーは、アプリケーション パーツの検出に必要な要件が満たされていないことが原因で発生します。 アプリが HTTP 404 エラーを返す場合、次の要件が満たされていることを確認します。

  • applicationName 設定は、検出に使用されるルート アセンブリに設定されている必要がある。 検出に使用されるルート アセンブリは、通常、エントリ ポイント アセンブリです。
  • ルート アセンブリに、検出に使用されるパーツへの参照が設定されている必要がある。 この参照は、直接的な参照でも推移的な参照でも構いません。
  • ルート アセンブリは、Web SDK を参照する必要がある。 このフレームワークには、検出に使用されるルート アセンブリに属性のスタンプを付けるロジックがあります。

作成者: Rick Anderson

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

"アプリケーション パーツ" は、アプリのリソースを抽象化したものです。 ASP.NET Core は、アプリケーション パーツを利用して、コントローラー、ビュー コンポーネント、タグ ヘルパー、Razor Pages、Razor コンパイル ソースなどを検出できます。 AssemblyPart はアプリケーション パーツです。 AssemblyPart はアセンブリ参照をカプセル化して、型とコンパイル参照を公開します。

"機能プロバイダー" は、アプリケーション パーツと連携し、ASP.NET Core アプリの機能を組み込みます。 アプリケーション パーツの主なユース ケースは、アセンブリから ASP.NET Core 機能を検出 (または読み込みを回避) するようにアプリを構成することです。 たとえば、複数のアプリで共通の機能を共有したいとします。 アプリケーション パーツを使用すると、コントローラー、ビュー、Razor Pages、Razor コンパイル ソース、タグ ヘルパーなどを含むアセンブリ (DLL) を複数のアプリと共有できます。 複数のプロジェクトでコードを複製するよりもアセンブリの共有をお勧めします。

ASP.NET Core アプリは ApplicationPart から機能を読み込みます。 AssemblyPart クラスは、アセンブリでバックアップされるアプリケーション パーツを表します。

ASP.NET Core 機能の読み込み

ApplicationPart および AssemblyPart クラスを使用し、ASP.NET Core 機能 (コントローラー、ビュー コンポーネントなど) を検出して読み込みます。 ApplicationPartManager は、使用可能なアプリケーション パーツと機能プロバイダーを追跡します。 ApplicationPartManagerStartup.ConfigureServices で構成されます。

public void ConfigureServices(IServiceCollection services)
{
    // Requires using System.Reflection;
    var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
    services.AddMvc()
        .AddApplicationPart(assembly)
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

次のコードは、AssemblyPart を使用して ApplicationPartManager を構成する別の方法を示しています。

public void ConfigureServices(IServiceCollection services)
{
    // Requires using System.Reflection;
    // Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
    var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
    var part = new AssemblyPart(assembly);
    services.AddMvc()
        .ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part))
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

上記 2 つのコード サンプルでは、アセンブリから SharedController が読み込まれます。 SharedController は、アプリケーションのプロジェクト内にありません。 WebAppParts ソリューションのサンプル ダウンロードを参照してください。

ビューを含める

アセンブリにビューを含めるには、Razor クラス ライブラリを使用します。

リソースの読み込みを防ぐ

アプリケーション パーツを使用して、特定のアセンブリまたは場所にあるソースの読み込みを "回避" することができます。 Microsoft.AspNetCore.Mvc.ApplicationParts コレクションのメンバーを追加または削除して、リソースを非表示にしたり使用可能にしたりします。 ApplicationParts コレクションでのエントリの順序は重要ではありません。 ApplicationPartManager を構成してから、コンテナーでサービスを構成するために使用します。 たとえば、AddControllersAsServices を呼び出す前に ApplicationPartManager を構成します。 リソースを削除するには、ApplicationParts コレクションに対して Remove を呼び出します。

次のコードでは、Microsoft.AspNetCore.Mvc.ApplicationParts を使用してアプリから MyDependentLibrary を削除します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApplicationPartManager(apm =>
            {
                var dependentLibrary = apm.ApplicationParts
                    .FirstOrDefault(part => part.Name == "MyDependentLibrary");

                if (dependentLibrary != null)
                {
                    apm.ApplicationParts.Remove(dependentLibrary);
                }
            });
}

ApplicationPartManager には次のパーツが含まれています。

  • アプリのアセンブリおよび依存アセンブリ。
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.Razor.

アプリケーション機能プロバイダー

アプリケーション機能プロバイダーはアプリケーション パーツを調べ、これらのパーツの機能を提供します。 次の ASP.NET Core 機能には組み込みの機能プロバイダーがあります。

機能プロバイダーは IApplicationFeatureProvider<TFeature> から継承されます。ここで T は機能の種類です。 機能プロバイダーは、前述の機能の種類のいずれについても実装できます。 ApplicationPartManager.FeatureProviders の機能プロバイダーの順序が実行時の動作に影響することがあります。 後から追加されたプロバイダーは、前に追加されたプロバイダーによって行われたアクションに対応できます。

使用可能な機能の表示

アプリで使用できる機能を列挙するには、依存関係の挿入によって ApplicationPartManager を要求します。

using AppPartsSample.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.ViewComponents;

namespace AppPartsSample.Controllers
{
    public class FeaturesController : Controller
    {
        private readonly ApplicationPartManager _partManager;

        public FeaturesController(ApplicationPartManager partManager)
        {
            _partManager = partManager;
        }

        public IActionResult Index()
        {
            var viewModel = new FeaturesViewModel();

            var controllerFeature = new ControllerFeature();
            _partManager.PopulateFeature(controllerFeature);
            viewModel.Controllers = controllerFeature.Controllers.ToList();

            var tagHelperFeature = new TagHelperFeature();
            _partManager.PopulateFeature(tagHelperFeature);
            viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();

            var viewComponentFeature = new ViewComponentFeature();
            _partManager.PopulateFeature(viewComponentFeature);
            viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();

            return View(viewModel);
        }
    }
}

ダウンロード サンプルでは、前のコードを使用してアプリの機能を表示します。

Controllers:
    - FeaturesController
    - HomeController
    - HelloController
    - GenericController`1
    - GenericController`1
Tag Helpers:
    - PrerenderTagHelper
    - AnchorTagHelper
    - CacheTagHelper
    - DistributedCacheTagHelper
    - EnvironmentTagHelper
    - Additional Tag Helpers omitted for brevity.
View Components:
    - SampleViewComponent

アプリケーション パーツでの検出

アプリケーション パーツを使用した開発では、HTTP 404 エラーが発生することは珍しくありません。 通常、これらのエラーは、アプリケーション パーツの検出に必要な要件が満たされていないことが原因で発生します。 アプリが HTTP 404 エラーを返す場合、次の要件が満たされていることを確認します。

  • applicationName 設定は、検出に使用されるルート アセンブリに設定されている必要がある。 検出に使用されるルート アセンブリは、通常、エントリ ポイント アセンブリです。
  • ルート アセンブリに、検出に使用されるパーツへの参照が設定されている必要がある。 この参照は、直接的な参照でも推移的な参照でも構いません。
  • ルート アセンブリは、Web SDK を参照する必要がある。
    • この ASP.NET Core フレームワークには、検出に使用されるルート アセンブリに属性のスタンプを付けるカスタム ビルド ロジックがあります。