这与依赖注入模式的 ASP.NET Core 实现有关。 Daisy 在 cmets 中指出的正是:
builder.Services.Configure(setupAction)
builder 是 IMvcBuilder。 builder.Services 是 IServiceCollection,也就是说,设置为在您的 asp-net 应用程序中可用的所有服务的主列表。在 Startup.cs 中设置了 FoobarService?那么IFoobarService 的定义 可能会位于ServiceCollection 中。等等。
ServiceCollection 附有大量扩展方法,可以更轻松地添加新服务。它还有.BuildServiceProvider(),它接受所有已注册的定义并创建一个服务工厂/提供者/缓存/解析器/事物,您/asp 可以稍后使用它来获取这些服务的实际实例。
然后,除了服务注册和构建工厂之外,由于“每个人都习惯”在 Startup.cs 中设置 ServiceCollection 的东西,因此还有一种配置更多细节的习惯,即通过 ServiceCollection 或姊妹对象上的更多扩展方法,服务可能需要在 Startup.cs 中。
现在,ASP.NET Core MVC 有一个用于处理应用程序配置的模块。它的设计是这样你定义一个类,通常称为whateverOptions,它将包含配置的某些部分,与whatever相关,并且稍后可以通过请求注入它来由任何服务检索。但是,由于我们将配置拆分为许多或多或少的上下文对象,如果我们将它们全部实例化(在一个地方?)并填充它们(在一个地方?!),那将是一个巨大的混乱。为方便起见,所有这些都将由框架创建。剩下的问题是,谁来填写实际设置。
.. 这与您发现的很接近。行:
builder.Services.Configure(setupAction)
接受 Action(接受 1 个参数的函子:Razor-Options)并将其注册到 big-bag-of-all-infos-on-any-service 中。它被注册为 RazorPagesOptions 的设置源。作为副作用,IoC 容器还获悉某些服务可能需要 RazorPagesOptions。
稍后,在运行时,当有人请求服务实例时,如果服务需要RazorPagesOptions,容器会检查它是否已经准备好。如果没有,则创建那些RazorPagesOptions 的实例(可能在单例模式下),但当然它最初是空的。然后,它通过所有已注册的设置源。依次调用每个这样的源,它们中的每个都获取 RazorPagesOptions 实例,并且它们每个都有机会用自己的部分设置填充它。最后,当所有都运行完毕后,RazorPagesOptions 的实例(..可能被缓存,然后..)被传递给需要它的服务。
我还没有说的一件事是Action<RazorPagesOptions> 的实例是从哪里来的。它可能来自 Startup.cs。在某处,您会有类似于以下内容的行:
services
.AddMvc() // registers MVC services in IoCC and gets you the IMvcBuilder
.AddRazorPagesOptions(options =>
{
options.RootDirectory = "....";
options.Conventions.Add(new FooConvention....);
...
});
此options => {..} 是Action<RazorPagesOptions>,将传递给 AddRazorPagesOptions,然后传递给 serviceCollection.Configure,并将注册为 RazorPagesOptions 的实际设置源。
要点:
- 假设您编写了一个 ASP.NET Core MVC 应用程序,那么它是您在 Startup.cs 中创建 Action 委托实例的代码 - 或者实际上是“编译器完成了它”,当您在调用 AddRazorPagesOptions 方法时编写了一个 lambda
- 此委托(可能)不会立即调用,而是存储以供以后使用
- 在应用程序的运行时生命周期中的某个时间,ASP.NET Core MVC 框架会注意到需要 RazorPagesOptions 并将创建实例。可能通过 Reflection 或 Activator.CreateInstance(Type) 所以你不会在任何地方找到
new RazorPagesOptions()
- 所有这些都特定于 ASP.NET Core MVC,而不是纯 C#
- 类似的机制和模式存在于其他库/框架/IoCC/等中
- 最后一点 - 我试图以“易于理解的方式”来写它,而不是 100% 精确。我在这里写的很多东西“有点不真实”,但恕我直言,足够接近