这实际上是对this question的跟进。其中一个Simple Injector开发人员指出了一个关于Simple Injector的有用信息,我认为让它更易于访问是件好事。
那么,使用Web API 1和.NET 4.0支持Simple Injector是否有任何技术障碍?源代码很容易下载和编译。 似乎可以正常工作。
答案 0 :(得分:8)
我们故意选择不支持.NET 4.0 for Web API,因为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论坛上的许多新问题,我们将不得不回答。
答案 1 :(得分:3)
这似乎不像评论,但它也不是一个答案 - 更像是一辆侧车。
我想补充一下@Steven的精彩解释。 CallContext.LogicalGetData()
是.NET Framework中的一个小宝石。不幸的是,它的行为随着时间的推移而发生了变化,并且确实有一些微妙之处。此外还缺乏有关该主题的信息。所以这里有一些资源: