使用应用程序部件共享控制器、视图、Razor Pages 等Share controllers, views, Razor Pages and more with Application Parts

本文内容

作者: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 功能Load ASP.NET Core features

使用 Microsoft.AspNetCore.Mvc.ApplicationPartsAssemblyPart 类发现并加载 ASP.NET Core 功能(控制器、视图组件等)。ApplicationPartManager 跟踪可用的应用程序部件和功能提供程序。ApplicationPartManager 中配置 Startup.ConfigureServices

  1. // Requires using System.Reflection;
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4. var assembly = typeof(MySharedController).Assembly;
  5. services.AddControllersWithViews()
  6. .AddApplicationPart(assembly);
  7. }

以下代码提供使用 ApplicationPartManager 配置 AssemblyPart 的可选方法:

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

前面的两个代码示例从程序集加载 SharedControllerSharedController 未在该应用的项目中。请参阅 WebAppParts 解决方案示例下载。

包含视图Include views

使用 Razor 类库将视图包含在程序集中。

阻止加载资源Prevent loading resources

可以使用应用程序部件来避免加载特定程序集或位置中的资源。添加或删除 Microsoft.AspNetCore.Mvc.ApplicationParts 集合的成员,将隐藏或提供资源。ApplicationParts 集合中条目的顺序并不重要。在使用 ApplicationPartManager 配置容器中的服务之前,对该类进行配置。例如,在调用 ApplicationPartManager 之前配置 AddControllersAsServicesRemove 集合上调用 ApplicationParts,将删除资源。

ApplicationPartManager 包括以下内容的部件:

  • 应用的程序集和依赖程序集。
  • Microsoft.AspNetCore.Mvc.ApplicationParts.CompiledRazorAssemblyPart
  • Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  • Microsoft.AspNetCore.Mvc.TagHelpers 列中的一个值匹配。
  • Microsoft.AspNetCore.Mvc.Razor 列中的一个值匹配。

功能提供程序Feature providers

应用程序功能提供程序用于检查应用程序部件,并为这些部件提供功能。以下 ASP.NET Core 功能有内置功能提供程序:

功能提供程序从 IApplicationFeatureProvider<TFeature> 继承,其中 T 是功能的类型。可以为上面列出的任意功能类型实现功能提供程序。ApplicationPartManager.FeatureProviders 中的功能提供程序的顺序可能影响运行时行为。较晚添加的提供程序可能会影响较早添加的提供程序执行的操作。

显示可用功能Display available features

通过ApplicationPartManager依存关系注入请求 即可以枚举应用的可用功能:

  1. using AppPartsSample.ViewModels;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.AspNetCore.Mvc.ApplicationParts;
  4. using Microsoft.AspNetCore.Mvc.Controllers;
  5. using System.Linq;
  6. using Microsoft.AspNetCore.Mvc.Razor.Compilation;
  7. using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
  8. using Microsoft.AspNetCore.Mvc.ViewComponents;
  9. namespace AppPartsSample.Controllers
  10. {
  11. public class FeaturesController : Controller
  12. {
  13. private readonly ApplicationPartManager _partManager;
  14. public FeaturesController(ApplicationPartManager partManager)
  15. {
  16. _partManager = partManager;
  17. }
  18. public IActionResult Index()
  19. {
  20. var viewModel = new FeaturesViewModel();
  21. var controllerFeature = new ControllerFeature();
  22. _partManager.PopulateFeature(controllerFeature);
  23. viewModel.Controllers = controllerFeature.Controllers.ToList();
  24. var tagHelperFeature = new TagHelperFeature();
  25. _partManager.PopulateFeature(tagHelperFeature);
  26. viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();
  27. var viewComponentFeature = new ViewComponentFeature();
  28. _partManager.PopulateFeature(viewComponentFeature);
  29. viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();
  30. return View(viewModel);
  31. }
  32. }
  33. }

下载示例使用前面的代码显示应用功能:

  1. Controllers:
  2. - FeaturesController
  3. - HomeController
  4. - HelloController
  5. - GenericController`1
  6. - GenericController`1
  7. Tag Helpers:
  8. - PrerenderTagHelper
  9. - AnchorTagHelper
  10. - CacheTagHelper
  11. - DistributedCacheTagHelper
  12. - EnvironmentTagHelper
  13. - Additional Tag Helpers omitted for brevity.
  14. View Components:
  15. - SampleViewComponent

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

使用应用程序部件进行开发时,会遇到 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 功能Load ASP.NET Core features

使用 ApplicationPartAssemblyPart 类发现并加载 ASP.NET Core 功能(控制器、视图组件等)。ApplicationPartManager 跟踪可用的应用程序部件和功能提供程序。ApplicationPartManager 中配置 Startup.ConfigureServices

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Requires using System.Reflection;
  4. var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
  5. services.AddMvc()
  6. .AddApplicationPart(assembly)
  7. .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  8. }

以下代码提供使用 ApplicationPartManager 配置 AssemblyPart 的可选方法:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Requires using System.Reflection;
  4. // Requires using Microsoft.AspNetCore.Mvc.ApplicationParts;
  5. var assembly = typeof(MySharedController).GetTypeInfo().Assembly;
  6. var part = new AssemblyPart(assembly);
  7. services.AddMvc()
  8. .ConfigureApplicationPartManager(apm => apm.ApplicationParts.Add(part))
  9. .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  10. }

前面的两个代码示例从程序集加载 SharedControllerSharedController 未在应用程序的项目中。请参阅 WebAppParts 解决方案示例下载。

包含视图Include views

使用 Razor 类库将视图包含在程序集中。

阻止加载资源Prevent loading resources

可以使用应用程序部件来避免加载特定程序集或位置中的资源。添加或删除 Microsoft.AspNetCore.Mvc.ApplicationParts 集合的成员,将隐藏或提供资源。ApplicationParts 集合中条目的顺序并不重要。在使用 ApplicationPartManager 配置容器中的服务之前,对该类进行配置。例如,在调用 ApplicationPartManager 之前配置 AddControllersAsServicesRemove 集合上调用 ApplicationParts,将删除资源。

以下代码使用 Microsoft.AspNetCore.Mvc.ApplicationParts 删除应用中的 MyDependentLibrary:[!code-csharp]

ApplicationPartManager 包括以下内容的部件:

  • 应用的程序集和依赖程序集。
  • Microsoft.AspNetCore.Mvc.TagHelpers 列中的一个值匹配。
  • Microsoft.AspNetCore.Mvc.Razor 列中的一个值匹配。

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

应用程序功能提供程序用于检查应用程序部件,并为这些部件提供功能。以下 ASP.NET Core 功能有内置功能提供程序:

功能提供程序从 IApplicationFeatureProvider<TFeature> 继承,其中 T 是功能的类型。可以为上面列出的任意功能类型实现功能提供程序。ApplicationPartManager.FeatureProviders 中的功能提供程序的顺序可能影响运行时行为。较晚添加的提供程序可能会影响较早添加的提供程序执行的操作。

显示可用功能Display available features

通过ApplicationPartManager依存关系注入请求 即可以枚举应用的可用功能:

  1. using AppPartsSample.ViewModels;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.AspNetCore.Mvc.ApplicationParts;
  4. using Microsoft.AspNetCore.Mvc.Controllers;
  5. using System.Linq;
  6. using Microsoft.AspNetCore.Mvc.Razor.Compilation;
  7. using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
  8. using Microsoft.AspNetCore.Mvc.ViewComponents;
  9. namespace AppPartsSample.Controllers
  10. {
  11. public class FeaturesController : Controller
  12. {
  13. private readonly ApplicationPartManager _partManager;
  14. public FeaturesController(ApplicationPartManager partManager)
  15. {
  16. _partManager = partManager;
  17. }
  18. public IActionResult Index()
  19. {
  20. var viewModel = new FeaturesViewModel();
  21. var controllerFeature = new ControllerFeature();
  22. _partManager.PopulateFeature(controllerFeature);
  23. viewModel.Controllers = controllerFeature.Controllers.ToList();
  24. var tagHelperFeature = new TagHelperFeature();
  25. _partManager.PopulateFeature(tagHelperFeature);
  26. viewModel.TagHelpers = tagHelperFeature.TagHelpers.ToList();
  27. var viewComponentFeature = new ViewComponentFeature();
  28. _partManager.PopulateFeature(viewComponentFeature);
  29. viewModel.ViewComponents = viewComponentFeature.ViewComponents.ToList();
  30. return View(viewModel);
  31. }
  32. }
  33. }

下载示例使用前面的代码显示应用功能:

  1. Controllers:
  2. - FeaturesController
  3. - HomeController
  4. - HelloController
  5. - GenericController`1
  6. - GenericController`1
  7. Tag Helpers:
  8. - PrerenderTagHelper
  9. - AnchorTagHelper
  10. - CacheTagHelper
  11. - DistributedCacheTagHelper
  12. - EnvironmentTagHelper
  13. - Additional Tag Helpers omitted for brevity.
  14. View Components:
  15. - SampleViewComponent

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

使用应用程序部件进行开发时,会遇到 HTTP 404 错误且并不鲜见。发生这些错误的原因通常是由于未满足某项针对应用程序部件发现方式的基本要求。如果应用返回 HTTP 404 错误,请验证是否满足以下要求:

  • 需要将 applicationName 设置设置为用于发现的根程序集。用于发现的根程序集通常是入口点程序集。
  • 根程序集需要引用用于发现的部件。引用可以是直接的,也可以是可传递的。
  • 根程序集需要引用 Web SDK。
    • ASP.NET Core 框架具有自定义生成逻辑,会将属性标记到用于发现的根程序集中。