【问题标题】:Why AddMvc expects Action<MvcOptions> instead of MvcOptions?为什么 AddMvc 需要 Action<MvcOptions> 而不是 MvcOptions?
【发布时间】:2019-06-06 10:37:54
【问题描述】:

我正在学习 ASP.NET Core,看到注册 MVC 服务是这样的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.MaxModelValidationErrors = 100;
    });
}

我的问题是,为什么AddMvc 方法需要Action&lt;MvcOptions&gt; 形式的选项?为什么我不能只创建一个MvcOptions 的实例并将其传递给函数?

【问题讨论】:

  • 如果在配置服务时提供了在请求管道中执行任何逻辑的灵活性
  • 只是描述选项的一种更实用的方式。它在灵活性/支持默认选项/等方面更好。恕我直言,它看起来也更好。
  • 为了详细说明 Ehsan 的评论,MVC 管道将配置自己的选项作为其创建和初始化的一部分。传入委托允许您根据 API 的要求在 MVC 的配置之上添加自定义行为,另一种方法是传入 MvcOptions - 复制您的选项,然后让 MVC 配置它自己的,这会很混乱/不必要的。
  • 之所以必须由实际开发人员解决,但如果您想深入兔子洞,可以查看源代码github.com/aspnet/AspNetCore/blob/…

标签: c# asp.net-core


【解决方案1】:

如果您查看AddMvc 的source,您会发现它不会为您创建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&lt;MvcOptions&gt; 的实例添加到依赖注入容器中,最终将在稍后的某个时间点运行您的委托。

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

这一切都提供了一些灵活性。您可以设置一个代表管道以按设定的顺序配置MvcOptions,其中每个配置步骤可能来自其他项目等。您甚至可以在调用AddMvc等之前先调用services.Configure&lt;MvcOptions&gt;(...)等.


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

AddMvcCoreadds its own configuration,而不是创建MvcOptions 本身的实例。它将一组IConfigureOptions&lt;MvcOptions&gt; 和IPostConfigureOptions&lt;MvcOptions&gt; 添加到依赖注入容器中。

这两个接口用于组装一种管道形式,其中所有 IConfigureOptions&lt;MvcOptions&gt; 首先运行(按照它们添加到 DI 的顺序),所有 IPostConfigureOptions&lt;MvcOptions&gt; 第二运行(再次,按顺序)。这允许AddMvcCore 提供一些默认值(使用IConfigureOptions&lt;MvcOptions&gt;),并且还提供了在应用所有其他配置后更改MvcOptions 的能力(使用IPostConfigureOptions&lt;MvcOptions&gt;)。

当您调用AddMvc 并提供一个委托时,该委托将在AddMvcCore 添加的IConfigureOptions&lt;MvcOptions&gt; 之后运行,这提供了在您的应用程序中覆盖这些默认值的能力。 p>

【讨论】:

    猜你喜欢
    • 2018-03-18
    • 2019-04-02
    • 2018-07-30
    • 2011-06-18
    • 2021-04-13
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2016-01-10
    相关资源
    最近更新 更多