Merge pull request #420 from benaadams/Features-perf
Remove FeatureReference indirection
This commit is contained in:
commit
d565659de7
|
|
@ -12,25 +12,44 @@ using Microsoft.AspNet.Http.Features.Authentication.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Authentication.Internal
|
namespace Microsoft.AspNet.Http.Authentication.Internal
|
||||||
{
|
{
|
||||||
public class DefaultAuthenticationManager : AuthenticationManager
|
public class DefaultAuthenticationManager : AuthenticationManager, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private FeatureReference<IHttpAuthenticationFeature> _authentication = FeatureReference<IHttpAuthenticationFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
private FeatureReference<IHttpResponseFeature> _response = FeatureReference<IHttpResponseFeature>.Default;
|
|
||||||
|
private IHttpAuthenticationFeature _authentication;
|
||||||
|
private IHttpResponseFeature _response;
|
||||||
|
|
||||||
public DefaultAuthenticationManager(IFeatureCollection features)
|
public DefaultAuthenticationManager(IFeatureCollection features)
|
||||||
{
|
{
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_authentication = null;
|
||||||
|
_response = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IHttpAuthenticationFeature HttpAuthenticationFeature
|
private IHttpAuthenticationFeature HttpAuthenticationFeature
|
||||||
{
|
{
|
||||||
get { return _authentication.Fetch(_features) ?? _authentication.Update(_features, new HttpAuthenticationFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new HttpAuthenticationFeature(),
|
||||||
|
ref _authentication);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpResponseFeature HttpResponseFeature
|
private IHttpResponseFeature HttpResponseFeature
|
||||||
{
|
{
|
||||||
get { return _response.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _response); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<AuthenticationDescription> GetAuthenticationSchemes()
|
public override IEnumerable<AuthenticationDescription> GetAuthenticationSchemes()
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,51 @@ using Microsoft.AspNet.Http.Features.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Internal
|
namespace Microsoft.AspNet.Http.Internal
|
||||||
{
|
{
|
||||||
public class DefaultConnectionInfo : ConnectionInfo
|
public class DefaultConnectionInfo : ConnectionInfo, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
private FeatureReference<IHttpConnectionFeature> _connection = FeatureReference<IHttpConnectionFeature>.Default;
|
private IHttpConnectionFeature _connection;
|
||||||
private FeatureReference<ITlsConnectionFeature> _tlsConnection = FeatureReference<ITlsConnectionFeature>.Default;
|
private ITlsConnectionFeature _tlsConnection;
|
||||||
|
|
||||||
public DefaultConnectionInfo(IFeatureCollection features)
|
public DefaultConnectionInfo(IFeatureCollection features)
|
||||||
{
|
{
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_connection = null;
|
||||||
|
_tlsConnection = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IHttpConnectionFeature HttpConnectionFeature
|
private IHttpConnectionFeature HttpConnectionFeature
|
||||||
{
|
{
|
||||||
get { return _connection.Fetch(_features) ?? _connection.Update(_features, new HttpConnectionFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new HttpConnectionFeature(),
|
||||||
|
ref _connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ITlsConnectionFeature TlsConnectionFeature
|
private ITlsConnectionFeature TlsConnectionFeature
|
||||||
{
|
{
|
||||||
get { return _tlsConnection.Fetch(_features) ?? _tlsConnection.Update(_features, new TlsConnectionFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new TlsConnectionFeature(),
|
||||||
|
ref _tlsConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IPAddress RemoteIpAddress
|
public override IPAddress RemoteIpAddress
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,22 @@ using Microsoft.AspNet.Http.Features.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Internal
|
namespace Microsoft.AspNet.Http.Internal
|
||||||
{
|
{
|
||||||
public class DefaultHttpContext : HttpContext
|
public class DefaultHttpContext : HttpContext, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly HttpRequest _request;
|
private readonly HttpRequest _request;
|
||||||
private readonly HttpResponse _response;
|
private readonly HttpResponse _response;
|
||||||
private readonly ConnectionInfo _connection;
|
private readonly ConnectionInfo _connection;
|
||||||
private readonly AuthenticationManager _authenticationManager;
|
private readonly AuthenticationManager _authenticationManager;
|
||||||
|
|
||||||
private FeatureReference<IItemsFeature> _items;
|
private IItemsFeature _items;
|
||||||
private FeatureReference<IServiceProvidersFeature> _serviceProviders;
|
private IServiceProvidersFeature _serviceProviders;
|
||||||
private FeatureReference<IHttpAuthenticationFeature> _authentication;
|
private IHttpAuthenticationFeature _authentication;
|
||||||
private FeatureReference<IHttpRequestLifetimeFeature> _lifetime;
|
private IHttpRequestLifetimeFeature _lifetime;
|
||||||
private FeatureReference<ISessionFeature> _session;
|
private ISessionFeature _session;
|
||||||
private WebSocketManager _websockets;
|
private WebSocketManager _websockets;
|
||||||
|
|
||||||
private IFeatureCollection _features;
|
private IFeatureCollection _features;
|
||||||
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
public DefaultHttpContext()
|
public DefaultHttpContext()
|
||||||
: this(new FeatureCollection())
|
: this(new FeatureCollection())
|
||||||
|
|
@ -43,37 +45,77 @@ namespace Microsoft.AspNet.Http.Internal
|
||||||
_response = new DefaultHttpResponse(this, features);
|
_response = new DefaultHttpResponse(this, features);
|
||||||
_connection = new DefaultConnectionInfo(features);
|
_connection = new DefaultConnectionInfo(features);
|
||||||
_authenticationManager = new DefaultAuthenticationManager(features);
|
_authenticationManager = new DefaultAuthenticationManager(features);
|
||||||
|
}
|
||||||
|
|
||||||
_items = FeatureReference<IItemsFeature>.Default;
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
_serviceProviders = FeatureReference<IServiceProvidersFeature>.Default;
|
{
|
||||||
_authentication = FeatureReference<IHttpAuthenticationFeature>.Default;
|
if (_cachedFeaturesRevision !=_features.Revision)
|
||||||
_lifetime = FeatureReference<IHttpRequestLifetimeFeature>.Default;
|
{
|
||||||
_session = FeatureReference<ISessionFeature>.Default;
|
_items = null;
|
||||||
|
_serviceProviders = null;
|
||||||
|
_authentication = null;
|
||||||
|
_lifetime = null;
|
||||||
|
_session = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IItemsFeature ItemsFeature
|
IItemsFeature ItemsFeature
|
||||||
{
|
{
|
||||||
get { return _items.Fetch(_features) ?? _items.Update(_features, new ItemsFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new ItemsFeature(),
|
||||||
|
ref _items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IServiceProvidersFeature ServiceProvidersFeature
|
IServiceProvidersFeature ServiceProvidersFeature
|
||||||
{
|
{
|
||||||
get { return _serviceProviders.Fetch(_features) ?? _serviceProviders.Update(_features, new ServiceProvidersFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new ServiceProvidersFeature(),
|
||||||
|
ref _serviceProviders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpAuthenticationFeature HttpAuthenticationFeature
|
private IHttpAuthenticationFeature HttpAuthenticationFeature
|
||||||
{
|
{
|
||||||
get { return _authentication.Fetch(_features) ?? _authentication.Update(_features, new HttpAuthenticationFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new HttpAuthenticationFeature(),
|
||||||
|
ref _authentication);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpRequestLifetimeFeature LifetimeFeature
|
private IHttpRequestLifetimeFeature LifetimeFeature
|
||||||
{
|
{
|
||||||
get { return _lifetime.Fetch(_features) ?? _lifetime.Update(_features, new HttpRequestLifetimeFeature()); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
() => new HttpRequestLifetimeFeature(),
|
||||||
|
ref _lifetime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISessionFeature SessionFeature
|
private ISessionFeature SessionFeature
|
||||||
{
|
{
|
||||||
get { return _session.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _session); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_features.Set(value);
|
||||||
|
_session = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IFeatureCollection Features { get { return _features; } }
|
public override IFeatureCollection Features { get { return _features; } }
|
||||||
|
|
@ -143,7 +185,7 @@ namespace Microsoft.AspNet.Http.Internal
|
||||||
if (feature == null)
|
if (feature == null)
|
||||||
{
|
{
|
||||||
feature = new DefaultSessionFeature();
|
feature = new DefaultSessionFeature();
|
||||||
_session.Update(_features, feature);
|
SessionFeature = feature;
|
||||||
}
|
}
|
||||||
feature.Session = value;
|
feature.Session = value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,16 @@ using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Internal
|
namespace Microsoft.AspNet.Http.Internal
|
||||||
{
|
{
|
||||||
public class DefaultHttpRequest : HttpRequest
|
public class DefaultHttpRequest : HttpRequest, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly DefaultHttpContext _context;
|
private readonly DefaultHttpContext _context;
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
private FeatureReference<IHttpRequestFeature> _request = FeatureReference<IHttpRequestFeature>.Default;
|
private IHttpRequestFeature _request;
|
||||||
private FeatureReference<IQueryFeature> _query = FeatureReference<IQueryFeature>.Default;
|
private IQueryFeature _query;
|
||||||
private FeatureReference<IFormFeature> _form = FeatureReference<IFormFeature>.Default;
|
private IFormFeature _form;
|
||||||
private FeatureReference<IRequestCookiesFeature> _cookies = FeatureReference<IRequestCookiesFeature>.Default;
|
private IRequestCookiesFeature _cookies;
|
||||||
|
|
||||||
public DefaultHttpRequest(DefaultHttpContext context, IFeatureCollection features)
|
public DefaultHttpRequest(DefaultHttpContext context, IFeatureCollection features)
|
||||||
{
|
{
|
||||||
|
|
@ -27,24 +28,58 @@ namespace Microsoft.AspNet.Http.Internal
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_request = null;
|
||||||
|
_query = null;
|
||||||
|
_form = null;
|
||||||
|
_cookies = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IHttpRequestFeature HttpRequestFeature
|
private IHttpRequestFeature HttpRequestFeature
|
||||||
{
|
{
|
||||||
get { return _request.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _request); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueryFeature QueryFeature
|
private IQueryFeature QueryFeature
|
||||||
{
|
{
|
||||||
get { return _query.Fetch(_features) ?? _query.Update(_features, new QueryFeature(_features)); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
(f) => new QueryFeature(f),
|
||||||
|
ref _query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IFormFeature FormFeature
|
private IFormFeature FormFeature
|
||||||
{
|
{
|
||||||
get { return _form.Fetch(_features) ?? _form.Update(_features, new FormFeature(this)); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
this,
|
||||||
|
(r) => new FormFeature(r),
|
||||||
|
ref _form);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRequestCookiesFeature RequestCookiesFeature
|
private IRequestCookiesFeature RequestCookiesFeature
|
||||||
{
|
{
|
||||||
get { return _cookies.Fetch(_features) ?? _cookies.Update(_features, new RequestCookiesFeature(_features)); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
(f) => new RequestCookiesFeature(f),
|
||||||
|
ref _cookies);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpContext HttpContext { get { return _context; } }
|
public override HttpContext HttpContext { get { return _context; } }
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@ using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Internal
|
namespace Microsoft.AspNet.Http.Internal
|
||||||
{
|
{
|
||||||
public class DefaultHttpResponse : HttpResponse
|
public class DefaultHttpResponse : HttpResponse, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly DefaultHttpContext _context;
|
private readonly DefaultHttpContext _context;
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private FeatureReference<IHttpResponseFeature> _response = FeatureReference<IHttpResponseFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
private FeatureReference<IResponseCookiesFeature> _cookies = FeatureReference<IResponseCookiesFeature>.Default;
|
|
||||||
|
private IHttpResponseFeature _response;
|
||||||
|
private IResponseCookiesFeature _cookies;
|
||||||
|
|
||||||
public DefaultHttpResponse(DefaultHttpContext context, IFeatureCollection features)
|
public DefaultHttpResponse(DefaultHttpContext context, IFeatureCollection features)
|
||||||
{
|
{
|
||||||
|
|
@ -23,14 +25,31 @@ namespace Microsoft.AspNet.Http.Internal
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_response = null;
|
||||||
|
_cookies = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IHttpResponseFeature HttpResponseFeature
|
private IHttpResponseFeature HttpResponseFeature
|
||||||
{
|
{
|
||||||
get { return _response.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _response); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private IResponseCookiesFeature ResponseCookiesFeature
|
private IResponseCookiesFeature ResponseCookiesFeature
|
||||||
{
|
{
|
||||||
get { return _cookies.Fetch(_features) ?? _cookies.Update(_features, new ResponseCookiesFeature(_features)); }
|
get
|
||||||
|
{
|
||||||
|
return FeatureHelpers.GetOrCreateAndCache(
|
||||||
|
this,
|
||||||
|
_features,
|
||||||
|
(f) => new ResponseCookiesFeature(f),
|
||||||
|
ref _cookies);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpContext HttpContext { get { return _context; } }
|
public override HttpContext HttpContext { get { return _context; } }
|
||||||
|
|
|
||||||
|
|
@ -10,25 +10,37 @@ using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Internal
|
namespace Microsoft.AspNet.Http.Internal
|
||||||
{
|
{
|
||||||
public class DefaultWebSocketManager : WebSocketManager
|
public class DefaultWebSocketManager : WebSocketManager, IFeatureCache
|
||||||
{
|
{
|
||||||
private IFeatureCollection _features;
|
private IFeatureCollection _features;
|
||||||
private FeatureReference<IHttpRequestFeature> _request = FeatureReference<IHttpRequestFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
private FeatureReference<IHttpWebSocketFeature> _webSockets = FeatureReference<IHttpWebSocketFeature>.Default;
|
|
||||||
|
private IHttpRequestFeature _request;
|
||||||
|
private IHttpWebSocketFeature _webSockets;
|
||||||
|
|
||||||
public DefaultWebSocketManager(IFeatureCollection features)
|
public DefaultWebSocketManager(IFeatureCollection features)
|
||||||
{
|
{
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_request = null;
|
||||||
|
_webSockets = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IHttpRequestFeature HttpRequestFeature
|
private IHttpRequestFeature HttpRequestFeature
|
||||||
{
|
{
|
||||||
get { return _request.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _request); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private IHttpWebSocketFeature WebSocketFeature
|
private IHttpWebSocketFeature WebSocketFeature
|
||||||
{
|
{
|
||||||
get { return _webSockets.Fetch(_features); }
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _webSockets); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsWebSocketRequest
|
public override bool IsWebSocketRequest
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Http.Features
|
||||||
|
{
|
||||||
|
internal sealed class FeatureHelpers
|
||||||
|
{
|
||||||
|
public static T GetAndCache<T>(
|
||||||
|
IFeatureCache cache,
|
||||||
|
IFeatureCollection features,
|
||||||
|
ref T cachedObject)
|
||||||
|
{
|
||||||
|
cache.CheckFeaturesRevision();
|
||||||
|
|
||||||
|
T obj = cachedObject;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = features.Get<T>();
|
||||||
|
cachedObject = obj;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetOrCreateAndCache<T>(
|
||||||
|
IFeatureCache cache,
|
||||||
|
IFeatureCollection features,
|
||||||
|
Func<T> factory,
|
||||||
|
ref T cachedObject)
|
||||||
|
{
|
||||||
|
cache.CheckFeaturesRevision();
|
||||||
|
|
||||||
|
T obj = cachedObject;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = features.Get<T>();
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = factory();
|
||||||
|
cachedObject = obj;
|
||||||
|
features.Set(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetOrCreateAndCache<T>(
|
||||||
|
IFeatureCache cache,
|
||||||
|
IFeatureCollection features,
|
||||||
|
Func<IFeatureCollection, T> factory,
|
||||||
|
ref T cachedObject)
|
||||||
|
{
|
||||||
|
cache.CheckFeaturesRevision();
|
||||||
|
|
||||||
|
T obj = cachedObject;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = features.Get<T>();
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = factory(features);
|
||||||
|
cachedObject = obj;
|
||||||
|
features.Set(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetOrCreateAndCache<T>(
|
||||||
|
IFeatureCache cache,
|
||||||
|
IFeatureCollection features,
|
||||||
|
HttpRequest request,
|
||||||
|
Func<HttpRequest, T> factory,
|
||||||
|
ref T cachedObject)
|
||||||
|
{
|
||||||
|
cache.CheckFeaturesRevision();
|
||||||
|
|
||||||
|
T obj = cachedObject;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = features.Get<T>();
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = factory(request);
|
||||||
|
cachedObject = obj;
|
||||||
|
features.Set(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Http.Features
|
||||||
|
{
|
||||||
|
internal interface IFeatureCache
|
||||||
|
{
|
||||||
|
void CheckFeaturesRevision();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,10 +9,12 @@ using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Features.Internal
|
namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
{
|
{
|
||||||
public class QueryFeature : IQueryFeature
|
public class QueryFeature : IQueryFeature, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private FeatureReference<IHttpRequestFeature> _request = FeatureReference<IHttpRequestFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
|
private IHttpRequestFeature _request;
|
||||||
|
|
||||||
private string _original;
|
private string _original;
|
||||||
private IReadableStringCollection _parsedValues;
|
private IReadableStringCollection _parsedValues;
|
||||||
|
|
@ -46,6 +48,20 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_request = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IHttpRequestFeature HttpRequestFeature
|
||||||
|
{
|
||||||
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _request); }
|
||||||
|
}
|
||||||
|
|
||||||
public IReadableStringCollection Query
|
public IReadableStringCollection Query
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -55,7 +71,7 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
return _parsedValues ?? ReadableStringCollection.Empty;
|
return _parsedValues ?? ReadableStringCollection.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var current = _request.Fetch(_features).QueryString;
|
var current = HttpRequestFeature.QueryString;
|
||||||
if (_parsedValues == null || !string.Equals(_original, current, StringComparison.Ordinal))
|
if (_parsedValues == null || !string.Equals(_original, current, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
_original = current;
|
_original = current;
|
||||||
|
|
@ -71,12 +87,12 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
{
|
||||||
_original = string.Empty;
|
_original = string.Empty;
|
||||||
_request.Fetch(_features).QueryString = string.Empty;
|
HttpRequestFeature.QueryString = string.Empty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_original = QueryString.Create(_parsedValues).ToString();
|
_original = QueryString.Create(_parsedValues).ToString();
|
||||||
_request.Fetch(_features).QueryString = _original;
|
HttpRequestFeature.QueryString = _original;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,12 @@ using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Features.Internal
|
namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
{
|
{
|
||||||
public class RequestCookiesFeature : IRequestCookiesFeature
|
public class RequestCookiesFeature : IRequestCookiesFeature, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private readonly FeatureReference<IHttpRequestFeature> _request = FeatureReference<IHttpRequestFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
|
private IHttpRequestFeature _request;
|
||||||
|
|
||||||
private StringValues _original;
|
private StringValues _original;
|
||||||
private IReadableStringCollection _parsedValues;
|
private IReadableStringCollection _parsedValues;
|
||||||
|
|
@ -43,6 +45,20 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_request = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IHttpRequestFeature HttpRequestFeature
|
||||||
|
{
|
||||||
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _request); }
|
||||||
|
}
|
||||||
|
|
||||||
public IReadableStringCollection Cookies
|
public IReadableStringCollection Cookies
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -52,7 +68,7 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
return _parsedValues ?? ReadableStringCollection.Empty;
|
return _parsedValues ?? ReadableStringCollection.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var headers = _request.Fetch(_features).Headers;
|
var headers = HttpRequestFeature.Headers;
|
||||||
StringValues current;
|
StringValues current;
|
||||||
if (!headers.TryGetValue(HeaderNames.Cookie, out current))
|
if (!headers.TryGetValue(HeaderNames.Cookie, out current))
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +97,7 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
{
|
{
|
||||||
if (_parsedValues == null || _parsedValues.Count == 0)
|
if (_parsedValues == null || _parsedValues.Count == 0)
|
||||||
{
|
{
|
||||||
_request.Fetch(_features).Headers.Remove(HeaderNames.Cookie);
|
HttpRequestFeature.Headers.Remove(HeaderNames.Cookie);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -94,7 +110,7 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_original = headers.ToArray();
|
_original = headers.ToArray();
|
||||||
_request.Fetch(_features).Headers[HeaderNames.Cookie] = _original;
|
HttpRequestFeature.Headers[HeaderNames.Cookie] = _original;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@ using Microsoft.AspNet.Http.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Http.Features.Internal
|
namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
{
|
{
|
||||||
public class ResponseCookiesFeature : IResponseCookiesFeature
|
public class ResponseCookiesFeature : IResponseCookiesFeature, IFeatureCache
|
||||||
{
|
{
|
||||||
private readonly IFeatureCollection _features;
|
private readonly IFeatureCollection _features;
|
||||||
private readonly FeatureReference<IHttpResponseFeature> _request = FeatureReference<IHttpResponseFeature>.Default;
|
private int _cachedFeaturesRevision = -1;
|
||||||
|
|
||||||
|
private IHttpResponseFeature _response;
|
||||||
private IResponseCookies _cookiesCollection;
|
private IResponseCookies _cookiesCollection;
|
||||||
|
|
||||||
public ResponseCookiesFeature(IFeatureCollection features)
|
public ResponseCookiesFeature(IFeatureCollection features)
|
||||||
|
|
@ -16,16 +18,29 @@ namespace Microsoft.AspNet.Http.Features.Internal
|
||||||
_features = features;
|
_features = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IFeatureCache.CheckFeaturesRevision()
|
||||||
|
{
|
||||||
|
if (_cachedFeaturesRevision != _features.Revision)
|
||||||
|
{
|
||||||
|
_response = null;
|
||||||
|
_cachedFeaturesRevision = _features.Revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IHttpResponseFeature HttpResponseFeature
|
||||||
|
{
|
||||||
|
get { return FeatureHelpers.GetAndCache(this, _features, ref _response); }
|
||||||
|
}
|
||||||
|
|
||||||
public IResponseCookies Cookies
|
public IResponseCookies Cookies
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_cookiesCollection == null)
|
if (_cookiesCollection == null)
|
||||||
{
|
{
|
||||||
var headers = _request.Fetch(_features).Headers;
|
var headers = HttpResponseFeature.Headers;
|
||||||
_cookiesCollection = new ResponseCookies(new HeaderDictionary(headers));
|
_cookiesCollection = new ResponseCookies(new HeaderDictionary(headers));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _cookiesCollection;
|
return _cookiesCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue