与应用程序部件共享控制器、视图、 Razor 页和更多内容Share controllers, views, Razor Pages and more with Application Parts

作者:Rick AndersonBy Rick Anderson

查看或下载示例代码如何下载View or download sample code (how to download)

应用程序部件是对应用资源的抽象化。**An Application Part is an abstraction over the resources of an app. 应用程序部件允许 ASP.NET Core 发现控制器、查看组件、标记帮助程序、 Razor 页面、razor 编译源等。Application Parts allow ASP.NET Core to discover controllers, view components, tag helpers, Razor Pages, razor compilation sources, and more. AssemblyPart 是应用程序部件。AssemblyPart is an Application part. AssemblyPart 用于封装程序集引用,并公开类型和编译引用。AssemblyPart encapsulates an assembly reference and exposes types and compilation references.

功能提供程序使用应用程序部件填充 ASP.NET Core 应用的功能。Feature providers work with application parts to populate the features of an ASP.NET Core app. 应用程序部件的主要用例是将应用配置为从程序集中发现(或避免加载)ASP.NET Core 功能。The main use case for application parts is to configure an app to discover (or avoid loading) ASP.NET Core features from an assembly. 例如,可能需要在多个应用之间共享通用功能。For example, you might want to share common functionality between multiple apps. 使用应用程序部件,你可以使用多个应用共享包含控制器、视图、 Razor 页面、razor 编译源、标记帮助程序以及更多应用程序 (DLL) 的程序集。Using Application Parts, you can share an assembly (DLL) containing controllers, views, Razor Pages, razor compilation sources, Tag Helpers, and more with multiple apps. 相对于在多个项目中复制代码,首选共享程序集。Sharing an assembly is preferred to duplicating code in multiple projects.

ASP.NET Core 应用从 ApplicationPart 加载功能。ASP.NET Core apps load features from ApplicationPart. AssemblyPart 类表示受程序集支持的应用程序部件。The AssemblyPart class represents an application part that's backed by an assembly.

加载 ASP.NET Core 功能Load ASP.NET Core features

使用 Microsoft.AspNetCore.Mvc.ApplicationPartsAssemblyPart 类发现并加载 ASP.NET Core 功能(控制器、视图组件等)。Use the Microsoft.AspNetCore.Mvc.ApplicationParts and AssemblyPart classes to discover and load ASP.NET Core features (controllers, view components, etc.). ApplicationPartManager 跟踪可用的应用程序部件和功能提供程序。The ApplicationPartManager tracks the application parts and feature providers available. Startup.ConfigureServices 中配置 ApplicationPartManagerApplicationPartManager is configured in Startup.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 的可选方法:The following code provides an alternative approach to configuring ApplicationPartManager using AssemblyPart:

// Requires using System.Reflection;
// Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
public void ConfigureServices(IServiceCollection services)
{
    var assembly = typeof(MySharedController).GetTypeInfo().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));
}

前面的两个代码示例从程序集加载 SharedControllerThe preceding two code samples load the SharedController from an assembly. SharedController 未在该应用的项目中。The SharedController is not in the app's project. 请参阅 WebAppParts 解决方案示例下载。See the WebAppParts solution sample download.

包含视图Include views

使用类库 Razor 将视图包含在程序集中。Use a Razor class library to include views in the assembly.

阻止加载资源Prevent loading resources

可以使用应用程序部件来避免加载特定程序集或位置中的资源。**Application parts can be used to avoid loading resources in a particular assembly or location. 添加或删除 Microsoft.AspNetCore.Mvc.ApplicationParts 集合的成员,将隐藏或提供资源。Add or remove members of the Microsoft.AspNetCore.Mvc.ApplicationParts collection to hide or make available resources. ApplicationParts 集合中条目的顺序并不重要。The order of the entries in the ApplicationParts collection isn't important. 在使用 ApplicationPartManager 配置容器中的服务之前,对该类进行配置。Configure the ApplicationPartManager before using it to configure services in the container. 例如,在调用 AddControllersAsServices 之前配置 ApplicationPartManagerFor example, configure the ApplicationPartManager before invoking AddControllersAsServices. ApplicationParts 集合上调用 Remove,将删除资源。Call Remove on the ApplicationParts collection to remove a resource.

ApplicationPartManager 包括以下内容的部件:The ApplicationPartManager includes parts for:

  • 应用的程序集和依赖程序集。The app's assembly and dependent assemblies.
  • Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyPart
  • Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  • Microsoft.AspNetCore.Mvc.TagHelpers.Microsoft.AspNetCore.Mvc.TagHelpers.
  • Microsoft.AspNetCore.Mvc.Razor.Microsoft.AspNetCore.Mvc.Razor.

功能提供程序Feature providers

应用程序功能提供程序用于检查应用程序部件,并为这些部件提供功能。Application feature providers examine application parts and provide features for those parts. 以下 ASP.NET Core 功能有内置功能提供程序:There are built-in feature providers for the following ASP.NET Core features:

功能提供程序从 IApplicationFeatureProvider<TFeature> 继承,其中 T 是功能的类型。Feature providers inherit from IApplicationFeatureProvider<TFeature>, where T is the type of the feature. 可以为上面列出的任意功能类型实现功能提供程序。Feature providers can be implemented for any of the previously listed feature types. ApplicationPartManager.FeatureProviders 中的功能提供程序的顺序可能影响运行时行为。The order of feature providers in the ApplicationPartManager.FeatureProviders can impact run time behavior. 较晚添加的提供程序可能会影响较早添加的提供程序执行的操作。Later added providers can react to actions taken by earlier added providers.

显示可用功能Display available features

通过依存关系注入请求 ApplicationPartManager 即可以枚举应用的可用功能:The features available to an app can be enumerated by requesting an ApplicationPartManager through dependency injection:

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);
        }
    }
}

下载示例使用前面的代码显示应用功能:The download sample uses the preceding code to display the app features:

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

应用程序部件中的发现Discovery in application parts

使用应用程序部件进行开发时,会遇到 HTTP 404 错误且并不鲜见。HTTP 404 errors are not uncommon when developing with application parts. 发生这些错误的原因通常是由于未满足某项针对应用程序部件发现方式的基本要求。These errors are typically caused by missing an essential requirement for how applications parts are discovered. 如果应用返回 HTTP 404 错误,请验证是否满足以下要求:If your app returns an HTTP 404 error, verify the following requirements have been met:

  • 需要将 applicationName 设置设置为用于发现的根程序集。The applicationName setting needs to be set to the root assembly used for discovery. 用于发现的根程序集通常是入口点程序集。The root assembly used for discovery is normally the entry point assembly.
  • 根程序集需要引用用于发现的部件。The root assembly needs to have a reference to the parts used for discovery. 引用可以是直接的,也可以是可传递的。The reference can be direct or transitive.
  • 根程序集需要引用 Web SDK。The root assembly needs to reference the Web SDK. 该框架的逻辑会将属性标记到用于发现的根程序集中。The framework has logic that stamps attributes into the root assembly that are used for discovery.

作者:Rick AndersonBy Rick Anderson

查看或下载示例代码如何下载View or download sample code (how to download)

应用程序部件是对应用资源的抽象化。**An Application Part is an abstraction over the resources of an app. 应用程序部件允许 ASP.NET Core 发现控制器、查看组件、标记帮助程序、 Razor 页面、razor 编译源等。Application Parts allow ASP.NET Core to discover controllers, view components, tag helpers, Razor Pages, razor compilation sources, and more. AssemblyPart 是一种应用程序部件。AssemblyPart is an Application part. AssemblyPart 用于封装程序集引用,并公开类型和编译引用。AssemblyPart encapsulates an assembly reference and exposes types and compilation references.

功能提供程序使用应用程序部件填充 ASP.NET Core 应用的功能。Feature providers work with application parts to populate the features of an ASP.NET Core app. 应用程序部件的主要用例是将应用配置为从程序集中发现(或避免加载)ASP.NET Core 功能。The main use case for application parts is to configure an app to discover (or avoid loading) ASP.NET Core features from an assembly. 例如,可能需要在多个应用之间共享通用功能。For example, you might want to share common functionality between multiple apps. 使用应用程序部件,你可以使用多个应用共享包含控制器、视图、 Razor 页面、razor 编译源、标记帮助程序以及更多应用程序 (DLL) 的程序集。Using Application Parts, you can share an assembly (DLL) containing controllers, views, Razor Pages, razor compilation sources, Tag Helpers, and more with multiple apps. 相对于在多个项目中复制代码,首选共享程序集。Sharing an assembly is preferred to duplicating code in multiple projects.

ASP.NET Core 应用从 ApplicationPart 加载功能。ASP.NET Core apps load features from ApplicationPart. AssemblyPart 类表示受程序集支持的应用程序部件。The AssemblyPart class represents an application part that's backed by an assembly.

加载 ASP.NET Core 功能Load ASP.NET Core features

使用 ApplicationPartAssemblyPart 类发现并加载 ASP.NET Core 功能(控制器、视图组件等)。Use the ApplicationPart and AssemblyPart classes to discover and load ASP.NET Core features (controllers, view components, etc.). ApplicationPartManager 跟踪可用的应用程序部件和功能提供程序。The ApplicationPartManager tracks the application parts and feature providers available. Startup.ConfigureServices 中配置 ApplicationPartManagerApplicationPartManager is configured in Startup.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 的可选方法:The following code provides an alternative approach to configuring ApplicationPartManager using AssemblyPart:

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);
}

前面的两个代码示例从程序集加载 SharedControllerThe preceding two code samples load the SharedController from an assembly. SharedController 未在应用程序的项目中。The SharedController is not in the application's project. 请参阅 WebAppParts 解决方案示例下载。See the WebAppParts solution sample download.

包含视图Include views

使用类库 Razor 将视图包含在程序集中。Use a Razor class library to include views in the assembly.

阻止加载资源Prevent loading resources

可以使用应用程序部件来避免加载特定程序集或位置中的资源。**Application parts can be used to avoid loading resources in a particular assembly or location. 添加或删除 Microsoft.AspNetCore.Mvc.ApplicationParts 集合的成员,将隐藏或提供资源。Add or remove members of the Microsoft.AspNetCore.Mvc.ApplicationParts collection to hide or make available resources. ApplicationParts 集合中条目的顺序并不重要。The order of the entries in the ApplicationParts collection isn't important. 在使用 ApplicationPartManager 配置容器中的服务之前,对该类进行配置。Configure the ApplicationPartManager before using it to configure services in the container. 例如,在调用 AddControllersAsServices 之前配置 ApplicationPartManagerFor example, configure the ApplicationPartManager before invoking AddControllersAsServices. ApplicationParts 集合上调用 Remove,将删除资源。Call Remove on the ApplicationParts collection to remove a resource.

以下代码使用 Microsoft.AspNetCore.Mvc.ApplicationParts 删除应用中的 MyDependentLibrary:[!code-csharp]The following code uses Microsoft.AspNetCore.Mvc.ApplicationParts to remove MyDependentLibrary from the app: [!code-csharp]

ApplicationPartManager 包括以下内容的部件:The ApplicationPartManager includes parts for:

  • 应用的程序集和依赖程序集。The app's assembly and dependent assemblies.
  • Microsoft.AspNetCore.Mvc.TagHelpers.Microsoft.AspNetCore.Mvc.TagHelpers.
  • Microsoft.AspNetCore.Mvc.Razor.Microsoft.AspNetCore.Mvc.Razor.

应用程序功能提供程序Application feature providers

应用程序功能提供程序用于检查应用程序部件,并为这些部件提供功能。Application feature providers examine application parts and provide features for those parts. 以下 ASP.NET Core 功能有内置功能提供程序:There are built-in feature providers for the following ASP.NET Core features:

功能提供程序从 IApplicationFeatureProvider<TFeature> 继承,其中 T 是功能的类型。Feature providers inherit from IApplicationFeatureProvider<TFeature>, where T is the type of the feature. 可以为上面列出的任意功能类型实现功能提供程序。Feature providers can be implemented for any of the previously listed feature types. ApplicationPartManager.FeatureProviders 中的功能提供程序的顺序可能影响运行时行为。The order of feature providers in the ApplicationPartManager.FeatureProviders can impact run time behavior. 较晚添加的提供程序可能会影响较早添加的提供程序执行的操作。Later added providers can react to actions taken by earlier added providers.

显示可用功能Display available features

通过依存关系注入请求 ApplicationPartManager 即可以枚举应用的可用功能:The features available to an app can be enumerated by requesting an ApplicationPartManager through dependency injection:

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);
        }
    }
}

下载示例使用前面的代码显示应用功能:The download sample uses the preceding code to display the app features:

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

应用程序部件中的发现Discovery in application parts

使用应用程序部件进行开发时,会遇到 HTTP 404 错误且并不鲜见。HTTP 404 errors are not uncommon when developing with application parts. 发生这些错误的原因通常是由于未满足某项针对应用程序部件发现方式的基本要求。These errors are typically caused by missing an essential requirement for how applications parts are discovered. 如果应用返回 HTTP 404 错误,请验证是否满足以下要求:If your app returns an HTTP 404 error, verify the following requirements have been met:

  • 需要将 applicationName 设置设置为用于发现的根程序集。The applicationName setting needs to be set to the root assembly used for discovery. 用于发现的根程序集通常是入口点程序集。The root assembly used for discovery is normally the entry point assembly.
  • 根程序集需要引用用于发现的部件。The root assembly needs to have a reference to the parts used for discovery. 引用可以是直接的,也可以是可传递的。The reference can be direct or transitive.
  • 根程序集需要引用 Web SDK。The root assembly needs to reference the Web SDK.
    • ASP.NET Core 框架具有自定义生成逻辑,会将属性标记到用于发现的根程序集中。The ASP.NET Core framework has custom build logic that stamps attributes into the root assembly that are used for discovery.