我正在学习ASP.NET Core,并且看到注册MVC服务看起来像这样:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.MaxModelValidationErrors = 100;
});
}
我的问题是,为什么
AddMvc
方法需要Action<MvcOptions>
形式的选项?为什么我不能只创建MvcOptions
实例并将其传递给函数? 最佳答案
如果查看source的AddMvc
,您会发现它没有为您创建MvcOptions
的实例:
public static IMvcBuilder AddMvc(this IServiceCollection services, Action<MvcOptions> setupAction)
{
...
var builder = services.AddMvc();
builder.Services.Configure(setupAction);
return builder;
}
相反,它使用
IServiceCollection.Configure
挂接到更通用的Options pattern in ASP.NET Core中。在幕后,这将 IConfigureOptions<MvcOptions>
实例添加到“依赖项注入(inject)”容器中,最终将在稍后的某个时间运行您的委托(delegate)。可以添加
IConfigureOptions<MvcOptions>
的多个实例,这些实例将按注册顺序运行。还有 IServiceCollection.PostConfigure
,它注册 IPostConfigureOptions<MvcOptions>
的实例-这些实例将在所有IConfigureOptions<MvcOptions>
实例(docs)之后运行。所有这些都提供了一定的灵活性。您可以建立代表以预定顺序配置
MvcOptions
的代表管道,每个配置步骤可能来自其他项目,等等。甚至可以在调用services.Configure<MvcOptions>(...)
等之前拥有自己的AddMvc
调用。将MVC服务添加到DI时,可以使用
AddMvc
或AddMvcCore
。在内部,AddMvc
调用AddMvcCore
,因此我们可以将AddMvc
视为AddMvcCore
的某种扩展。AddMvcCore
adds its own configuration,使用Options pattern in ASP.NET Core。 MvcOptions
不会创建AddMvcCore
本身的实例,而是将一组 IConfigureOptions<MvcOptions>
和 IPostConfigureOptions<MvcOptions>
添加到Dependency Injection容器中。这两个接口(interface)用于组装一种形式的管道,其中所有
IConfigureOptions<MvcOptions>
首先运行(按它们添加到DI的顺序),所有IPostConfigureOptions<MvcOptions>
随后运行(再次按顺序)。这允许AddMvcCore
提供一些默认值(使用IConfigureOptions<MvcOptions>
),并且还提供一旦应用了所有其他配置(使用MvcOptions
)就可以对IPostConfigureOptions<MvcOptions>
进行更改的功能。当您调用
AddMvc
并提供委托(delegate)时,该委托(delegate)将在IConfigureOptions<MvcOptions>
添加的AddMvcCore
之后运行,这提供了在应用程序中覆盖这些默认值的能力。关于c# - 为什么AddMvc需要Action <MvcOptions>而不是MvcOptions?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54147660/