如果我给AddControllersWithViews()添加一个扩展,它是否也适用于AddRazorPages()?

4
如果我在应用程序中同时使用.AddControllersWithViews().AddRazorPages(),并且我想在它们上调用一个扩展方法,那么我是否必须将其添加到两者中,并且将其添加到这两个服务中是否安全?
在Asp Core 2.1中,我们在Startup.cs中使用了扩展方法.AddMvc()。在Asp Core 3+中,它被拆分为.AddControllersWithViews().AddRazorPages()。在混合了传统MVC和较新的Razor视图的应用程序中,开发人员可以选择使用.AddControllersWithViews().AddRazorPages()两者,或者只使用旧的.AddMvc()。这在Microsoft文档中有提到,并且还可以在源代码中看到。
在我的应用程序中,我使用了.AddControllersWithViews().AddRazorPages()两者,而不是只使用.AddMvc()
var scwv = services.AddControllersWithViews();  
var srp = services.AddRazorPages(); 

如果决定添加Netwonsoft Json支持,使用.AddNewtonsoftJson(),我需要在两个地方都添加.AddNewtonsoftJson()扩展吗?例如:
scwv.AddNewtonsoftJson()
srp.AddNewtonsoftJson()

我只需要使用以上哪个声明中的一个吗?
同样地,如果我决定添加 .AddRazorRuntimeCompilation() 以便在更改 .cshtml 文件时无需停止和启动项目,我是否需要将 .AddRazorRuntimeCompilation() 扩展都加上,就像这样:
scwv.AddRazorRuntimeCompilation()
srp.AddRazorRuntimeCompilation()

我只能使用上述其中一种语句吗?

[我知道更简单的选择是改为使用 .AddMvc(),不需要考虑任何其他事情。但是我正在尝试了解中间件的工作原理,以及是否向其中一个添加扩展将同时适用于两者,或者将相同的扩展添加到两个中间件是否会导致一些问题或冲突,因为许多基础功能是共享的,并且所有中间件都被一起添加]

1个回答

3
首先,在ConfigureServices方法中运行的Add~方法通常是以可重复调用的方式构建的,不会产生任何其他副作用。它们大多只是为依赖注入容器添加或配置服务,并以不会在重复调用时添加额外服务或替换之前的注册方式执行。
服务生成器(Service builders),例如从AddControllers()AddRazorPages()等方法返回的MvcBuilder,通常只是限制特定范围内的附加Add~方法的一种方式。例如,AddNewtonsoftJson只适用于与MVC相关的设置。还有许多其他扩展方法仅适用于某些其他设置。因此,为了避免在服务集合services中提供所有这些方法,并严重阻碍发现性,使用了生成器模式进行作用域限制。
在幕后,这些生成器仍将服务直接添加到服务集合中。因此,通常无论您从哪里获取生成器,都不太重要,只要您以某种方式获取它即可。

[...]我是否需要同时添加到两者中?

所以不需要在AddControllersWithViews()AddRazorPages()中同时添加。两个调用都将返回一个MVC生成器,该生成器将向同一服务集合添加服务。因此,您可以在任何一个生成器上调用AddNewtonsoftJson()

[...]同时添加是否安全?

是的,你仍然可以在两个上都调用它。
话虽如此,如果您想设置MVC和Razor页面,即同时调用AddControllersWithViews()AddRazorPages(),那么您也可以直接调用AddMvc(),因为正是这个方法做的事情。然后您就不需要再考虑添加到哪个MVC生成器了;)

谢谢你的解释,这真的很有帮助。至于AddMvc() - 我没有直接切换到它的原因是我担心微软只是为了向后兼容而保留它,并且可能会在未来将其删除(我可能是错的,这只是一个猜测)。 - Gary
1
是的,AddMvc可能最终会被停用,但我认为它至少会一直保留到ASP.NET Core 6,因为目前没有任何计划停用它。因此,您可以放心地继续使用它相当长的一段时间。 - poke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接