为什么AddMvc需要Action <mvcoptions>而不是MvcOptions?

时间:2019-01-11 13:38:31

标签: c# asp.net-core

我正在学习ASP.NET Core,并且看到注册MVC服务看起来像这样:

import csv
csvfile = open("logindetails.csv")
reader = csv.reader(csvfile)
for row in reader:
    print([row[0]])


username = input("Type a username to remove:")
usernamelist = [username]
print(usernamelist)
row[0].remove(username)

我的问题是,为什么public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.MaxModelValidationErrors = 100; }); } 方法要求使用AddMvc形式的选项?为什么我不能仅创建Action<MvcOptions>的实例并将其传递给函数?

1 个答案:

答案 0 :(得分:9)

如果您查看AddMvc的{​​{3}},您会发现它不会为您创建MvcOptions的实例:

public static IMvcBuilder AddMvc(this IServiceCollection services, Action<MvcOptions> setupAction)
{
    ...

    var builder = services.AddMvc();
    builder.Services.Configure(setupAction);

    return builder;
}

相反,它使用source来插入更通用的IServiceCollection.Configure。在幕后,这会将Options pattern in ASP.NET Core的实例添加到“依赖项注入”容器中,最终将在以后的某个时刻运行您的委托。

可以添加IConfigureOptions<MvcOptions>多个实例,这些实例将按注册顺序运行。还有IConfigureOptions<MvcOptions>,它注册IServiceCollection.PostConfigure的实例-这些实例将在所有IConfigureOptions<MvcOptions>实例(IPostConfigureOptions<MvcOptions>)的之后运行。

这一切都提供了一定的灵活性。您可以建立代表以预定顺序配置MvcOptions的代表管道,每个配置步骤可能来自其他项目,等等。甚至可以在调用{之前,先调用services.Configure<MvcOptions>(...) {1}},等等。


将MVC服务添加到DI时,可以使用AddMvcAddMvc。在内部,AddMvcCore调用AddMvc,因此我们可以将AddMvcCore视为AddMvc的某种扩展。

AddMvcCore docs,使用adds its own configurationAddMvcCore本身并未创建MvcOptions的实例,而是向依赖注入容器中添加了一组Options pattern in ASP.NET CoreIConfigureOptions<MvcOptions>

这两个接口用于组装某种形式的管道,所有AddMvcCore首先运行(按照它们添加到DI的顺序),所有IConfigureOptions<MvcOptions>之后运行(再次按照顺序) 。这样,IPostConfigureOptions<MvcOptions>可以提供一些默认值(使用AddMvcCore),并且还提供了一旦应用了所有其他配置(使用IConfigureOptions<MvcOptions>)就可以对MvcOptions进行更改的功能。

调用IPostConfigureOptions<MvcOptions>并提供委托时,该委托将在AddMvc添加的IConfigureOptions<MvcOptions>之后运行 ,从而可以覆盖这些默认值在您的应用程序中。