这两个属性有什么不同?
我可以使用HttpContext.Items
代替HttpContext.Features
在中间件
之间共享数据。我唯一看到的区别是,我要为一个键告诉Items
,它会给我一个对象,我需要强制转换。在Features
中,这个转换可以自动完成。
它们背后还有其他东西吗?
这两个属性有什么不同?
我可以使用HttpContext.Items
代替HttpContext.Features
在中间件
之间共享数据。我唯一看到的区别是,我要为一个键告诉Items
,它会给我一个对象,我需要强制转换。在Features
中,这个转换可以自动完成。
它们背后还有其他东西吗?
HttpContext.Items
被设计用来存储 Key-Value-Pair
,而 HttpContext.Features
被设计用来存储 Type-Instance-Pair
。更具体地说,HttpContext.Items
被设计用于在当前请求范围内共享项目,而 HttpContext.Features
是 IFeatureCollection
实例,绝不能像这样使用。
IFeatureCollection
接口表示 HTTP 功能的集合,例如:
IAuthenticationFeature
存储原始路径基础和原始路径。ISessionFeature
存储当前会话。IHttpConnectionFeature
存储底层连接。Type-Instance-Pair
,该接口有三个重要方法:public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>{
// ...
object this[Type key] { get; set; }
TFeature Get<TFeature>();
void Set<TFeature>(TFeature instance);
}
实现部分 (FeatureCollection
) 将简单地将值转换为所需的类型:
public class FeatureCollection : IFeatureCollection
{
// ... get the required type of feature
public TFeature Get<TFeature>()
{
return (TFeature)this[typeof(TFeature)]; // note: cast here!
}
public void Set<TFeature>(TFeature instance)
{
this[typeof(TFeature)] = instance; // note!
}
}
这是有意为之的设计。因为没有必要存储两个 IHttpConnectionFeature
实例或两个 ISession
实例。
虽然你可以使用 FeatureCollection
存储一些 Type-Value
对,但最好不要这样做。正如你所看到的,如果某个类型已经存在于集合中,Set<TFeature>(TFeature instance)
将简单地替换旧实例;这也意味着如果你有两个相同类型的对象,将会出现一个 bug。
HttpContext.Items
旨在共享短期的每个请求数据,正如您所提到的。
HttpContext.Features
旨在共享各种HTTP功能,允许中间件创建或修改应用程序的托管管道。它已经填充了来自.NET的几个特性,例如IHttpSendFileFeature
。
您应该使用HttpContext.Items
存储数据,并使用HttpContext.Features
添加其他中间件类可能需要的任何新的HTTP功能。
HttpContext.Features
的生命周期是多久? - Mohammad Barbast
HttpContext.Items
对于每个请求而言是短暂的,那么HttpContext.Features
的成员寿命是多久? - Mohammad BarbastIServer
接口的实现有关。事实上,即使在HttpContext
之前,服务器实现本身和一些功能(如ServerAddressFeature
)也是由服务器实现创建的。请参见Kestrel。 - itminus