问题描述
我正在学习ASP.NET Core,并且看到注册MVC服务看起来像这样:
I'm learning ASP.NET Core and I see that registering an MVC service looks like this:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.MaxModelValidationErrors = 100; }); }
我的问题是,为什么AddMvc方法需要Action<MvcOptions>形式的选项?为什么我不能仅创建MvcOptions的实例并将其传递给函数?
My question is, why does the AddMvc method require options in the form of Action<MvcOptions>? Why can't I just create an instance of MvcOptions and pass it to the function?
推荐答案
如果您查看源为AddMvc,您会发现它没有为MvcOptions创建实例你:
If you look at the source for AddMvc, you'll see that it doesn't create an instance of MvcOptions for you:
public static IMvcBuilder AddMvc(this IServiceCollection services, Action<MvcOptions> setupAction) { ... var builder = services.AddMvc(); builder.Services.Configure(setupAction); return builder; }
相反,它使用 IServiceCollection.Configure 连接到更通用的 ASP.NET Core中的选项模式.在幕后,这添加了 IConfigureOptions<MvcOptions> 到依赖注入容器,它将最终在以后的某个时间运行您的委托.
Instead, it uses IServiceCollection.Configure to hook into the more general Options pattern in ASP.NET Core. Behind the scenes, this adds an instance of IConfigureOptions<MvcOptions> to the Dependency Injection container, which will end up running your delegate at some point later in time.
可以添加的多个实例,这些实例将按注册顺序运行.还有一个,它注册 IPostConfigureOptions<MvcOptions> -这些实例将在所有IConfigureOptions<MvcOptions>实例之后 (文档).
It's possible to add multiple instances of IConfigureOptions<MvcOptions>, which will be run in order of registration. There's also IServiceCollection.PostConfigure, which registers instances of IPostConfigureOptions<MvcOptions> - these instances will run after all of the IConfigureOptions<MvcOptions> instances (docs).
这一切都提供了一定的灵活性.您可以建立代表以预定顺序配置MvcOptions的代表管道,其中每个配置步骤可能来自其他项目,等等.甚至在调用AddMvc之前,甚至可以自己调用services.Configure<MvcOptions>(...)
This all offers some flexibility. You can set up a pipeline of delegates for configuring MvcOptions in a set order, where each configuration step might come from other projects, etc. You could even have your own call to services.Configure<MvcOptions>(...) before your call to AddMvc, etc.
将MVC服务添加到DI时,可以使用AddMvc或AddMvcCore.在内部,AddMvc调用AddMvcCore,因此我们可以将AddMvc视为AddMvcCore的某种扩展.
When adding the MVC services to DI, it's possible to use either AddMvc or AddMvcCore. Internally, AddMvc calls AddMvcCore, so we can think of AddMvc as some kind of extension of AddMvcCore.
AddMvcCore 使用
AddMvcCore adds its own configuration, using the Options pattern in ASP.NET Core. Rather than creating an instance of MvcOptions itself, AddMvcCore adds a set of IConfigureOptions<MvcOptions> and IPostConfigureOptions<MvcOptions> to the Dependency Injection container.
这两个接口用于组装某种形式的管道,其中所有IConfigureOptions<MvcOptions>首先运行(按它们添加到DI的顺序),所有IPostConfigureOptions<MvcOptions>随后运行(再次按顺序).这样,AddMvcCore可以提供一些默认值(使用IConfigureOptions<MvcOptions>),还可以在应用了所有其他配置(使用IPostConfigureOptions<MvcOptions>)后对MvcOptions进行更改.
These two interfaces are used to assemble a form of pipeline, where all IConfigureOptions<MvcOptions> run first (in the order they're added to DI) and all IPostConfigureOptions<MvcOptions> run second (again, in order). This allows AddMvcCore to provide some defaults (using IConfigureOptions<MvcOptions>) and also provides the ability to make changes to MvcOptions once all other configurations have been applied (using IPostConfigureOptions<MvcOptions>).
当您调用AddMvc并提供委托时,该委托将在AddMvcCore添加的IConfigureOptions<MvcOptions>之后的之后运行.
When you call AddMvc and provide a delegate, said delegate will run after the IConfigureOptions<MvcOptions> added by AddMvcCore, which provides the ability to override these defaults within your application.
这篇关于为什么AddMvc需要Action< MvcOptions>而不是MvcOptions?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!