我们故意选择不支持 Web API 的 .NET 4.0,因为 WebApiRequestLifestyle 使用了 CallContext.LogicalGetData,它在 .NET 4.0 下的行为不同。这种行为非常不同,以至于在后台线程中使用嵌套的ExecutionContextScope 实例和并行运行的Tasks 时可能会导致错误。
这方面的变化是,在 .NET 4.5 中,逻辑调用上下文显示为copy-on-write behavior,这意味着当从并行操作中更改逻辑调用上下文时,它不会影响产生的原始操作这种并行操作。在 .NET 4.0 中,在并行操作中对逻辑调用上下文的任何更改都可以在主操作中观察到。
我们决定依赖 .NET 4.5 的这种写时复制行为,因为它允许从主操作产生多个并行操作,这些操作都可以启动它们自己的 ExecutionContextScope(这就是 Web API集成包在后台使用)隔离运行。这允许它们拥有自己的子作用域,并且当作用域被释放时,它们会在主操作的作用域中再次运行。从后台线程中的新范围开始通常是您想要做的,因为否则您的组件将被并行访问,而它们可能根本不是线程安全的。启动新范围可确保从容器解析新对象图时,如果新实例注册为 Per Web API Request 或 Per Execution Scope,则会创建新实例。
如果没有这种写复制行为,并行操作会相互干扰,并且会看到其他并行操作的范围,这会导致这些范围嵌套,而实际上它们不会嵌套,而是重叠。这将导致各种问题,例如导致退回到另一个并行操作的范围(而不是退回到主操作的范围)。这当然是不正确的行为。
只要您只在异步流程中启动新的ExecutionContextScope(或根本不启动新的作用域)而不是在并行操作中启动新的作用域,问题就不存在并且您的代码将运行在 .NET 4.0 和 .NET 4.5 下相同。
但是由于这种行为根本不同,可能会导致各种问题,或者当它似乎工作时,当您切换到 .NET 4.5 时可能会再次中断,我们决定不要尝试这样做是明智的完全支持 .NET 4.0。这可以防止开发人员落入这个陷阱,并且使我们自己的工作更容易,因为我们不必记录这个根本差异,它也为我们节省了大量的支持时间,因为无论文档多么好,无论如何,开发人员都会尝试在 .NET 4.0 下使用它,这可能会在 Stackoverflow 和 Simple Injector 论坛上引发许多新问题,我们将不得不回答这些问题。