What is the differences between these two Properties?
I can use HttpContext.Items
instead of HttpContext.Features
to share data between middlewares
. The only difference I see is that I tell Items
for a key and it gives me an object and I have to cast it. This casting can be done in Features
automatically.
Is there something else behind them?
The biggest difference is that the HttpContext.Items
is designed to store Key-Value-Pair
, while the HttpContext.Features
is designed to store Type-Instance-Pair
.
To be more clear, HttpContext.Items
is designed to share items within the scope of current request, while the HttpContext.Features
, which is an instance of IFeatureCollection
, is by no means to be used like that .
The IFeatureCollection
interface represents a collection of HTTP features, such as:
IAuthenticationFeature
which stores original PathBase and original Path.ISessionFeature
which stores current Session.IHttpConnectionFeature
which stores the underlying connection.To help store and retrieve a Type-Instance-Pair
, the interface has three important methods:
public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>{
// ...
object this[Type key] { get; set; }
TFeature Get<TFeature>();
void Set<TFeature>(TFeature instance);
}
and the implementation (FeatureCollection
) will simply cast the value into required type:
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!
}
}
This is by design. Because there's no need to store two IHttpConnectionFeature
instances or two ISession
instances.
While you can store some Type-Value
pairs with FeatureCollection
, you'd better not . As you see, the Set<TFeature>(TFeature instance)
will simply replace the old one if the some type already exists in the collection; it also means there will be a bug if you have two of the same type.