如果我向 AddControllersWithViews() 添加扩展,它是否也适用于 AddRazorPages()

If I add an extension to AddControllersWithViews() will it also apply to AddRazorPages()

如果我在应用程序中同时使用 .AddControllersWithViews().AddRazorPages(),并且我想对它们调用扩展方法,我是否必须将其添加到两者中,添加是否安全两者都有吗?

在Asp Core 2.1中,在Startup.cs中我们曾经使用扩展方法.AddMvc()。 在 Asp Core 3+ 中,它被分解为 .AddControllersWithViews().AddRazorPages()。在混合了传统 MVC 和较新的 Razor 视图的应用程序中,开发人员可以选择同时使用 .AddControllersWithViews().AddRazorPages(),或者只使用旧的 .AddMvc()Microsoft docs and can also be seen in the source code.

中提到了这一点

在我的应用程序中,我同时使用了 .AddControllersWithViews().AddRazorPages(),而不仅仅是 .AddMvc()

var scwv = services.AddControllersWithViews();  
var srp = services.AddRazorPages(); 

如果决定为 .AddNewtonsoftJson() 添加 Netwonsoft Json 支持,我是否需要为两者添加 .AddNewtonsoftJson() 扩展?喜欢

scwv.AddNewtonsoftJson()
srp.AddNewtonsoftJson()

或者我可以只使用上述语句之一吗?

同样,如果我决定添加 .AddRazorRuntimeCompilation() 这样我就不必在每次更改 .cshtml 文件时都停止并启动项目,我是否需要添加 .AddRazorRuntimeCompilation() 像这样对两者进行扩展:

scwv.AddRazorRuntimeCompilation()
srp.AddRazorRuntimeCompilation()

或者我可以只使用上述语句之一吗?

[我意识到更简单的选择是更改 .AddMvc() 的使用,而不考虑任何这些。但是我试图了解中间件是如何工作的,以及向其中一个添加扩展是否会对两者都起作用,或者向它们添加相同的扩展是否会导致一些问题或冲突,因为许多底层功能被共享,所有中间件都被添加在一起]

首先,您可以在 ConfigureServices 方法中 运行 的 Add~ 方法通常以一种您可以重复调用它们而没有任何额外副作用的方式构建。在大多数情况下,他们只是为依赖注入容器添加或配置服务,并且他们这样做的方式不会在重复调用时添加额外的服务,也不会替换以前的注册。

服务构建器,例如从 AddControllers()AddRazorPages() 等方法获取 returned 的 MvcBuilder,通常只是一种限制附加 Add~ 方法的方法一定范围。例如,AddNewtonsoftJson 仅作为 MVC 相关设置的“配置”相关。还有许多其他扩展方法仅适用于某些其他设置。因此,为了避免所有这些都在服务集合中可用 services,并严重阻碍可发现性,它们使用构建器模式进行范围界定。

在幕后,这些构建器仍然会直接将服务添加到服务集合中。因此,从哪里获得构建器通常并不重要,只要您以某种方式获得即可。

[…] do I have to add it to both

所以不,您不必将它添加到 AddControllersWithViews()AddRazorPages()。这两个调用都将 return 一个 MVC 构建器,它将服务添加到同一个服务集合中。因此,您可以在任一构建器上调用 AddNewtonsoftJson()

[…] and is it safe to add it to both?

是的,您仍然可以同时调用它。


综上所述,如果您想设置 MVC 和 Razor 页面,即同时调用 AddControllersWithViews()AddRazorPages(),那么您也可以只调用 AddMvc(),因为 that’s exactly what that method does。然后您不再需要考虑需要将调用添加到哪个 MVC 构建器 ;)