Startup.cs 中的这个 C# HttpContext 上下文从何而来?

Where does this C# HttpContext context in Startup.cs come from?

所以我遇到了这个 RazorPages sample code

    using Microsoft.AspNetCore.Mvc;

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

我的问题是,context 从何而来?我在看

options => { ... } 

作为一个匿名委托函数,lambda 运算符左侧的部分是选项,是被送入 context 所在的表达式块的参数。但是 Startup.cs 中的其他任何地方都没有显示上下文,当我注释掉

时,编译器似乎并不介意
using Microsoft.AspNetCore.Mvc;

.Net 是否在幕后透明地做一些事情以向 options.CheckConsentNeeded 提供 context,如果我手写该语句我怎么知道 context 可用,它来自哪里?

Configure 允许您传入一个 lambda 来配置您的选项。看看这个人为的例子来解释发生了什么。

// we have an options class that will hold all the props to configure
// our coolie policy
public class Options
{
    public bool UseConsent { get; set; }
}

// this emulates the signature for services.Configure. It takes a lambda
// and simply executes it, enabling the caller to manage the settings
public static void Configure(Action<Options> callback)
{
    //create new options instance
    var options = new Options();
    // allow caller to access this instance and set properties
    callback(options);
    Console.WriteLine(options.UseConsent); // this will print true
}


public static void Main()
{
    Configure(options =>
    {
        options.UseConsent = true;
    });
    Console.ReadLine();
}

正如你所看到的,没有什么神奇的事情发生,你之所以可以设置选项或不设置选项,是因为Configure过载,允许你传入或不传入lambda。

CheckConsentNeeded 属性 接受 Func<HttpContext, bool>.

的委托

Func<HttpContext, bool> 在 C# 中可以表示一个方法,该方法采用 HttpContext 和 returns 一个 bool 值的参数。

bool MyFunction(HttpContext context)
{
}

在您的例子中,您将 lambda expression 分配给了 属性,并且 context 表示类型 HttpContext 的参数。 context是一个名字,可以改成其他名字,比如ctxc

你不需要添加using来使用context,但是如果你在你的代码中使用它的类型HttpContext,你必须使用using

To allow the use of types in a namespace

在运行时,当委托的调用者(很可能在中间件中)调用委托时,它会将 HttpContext 的实例作为参数传递给分配给 CheckConsentNeeded 的委托 属性.