Add Session feature, object model, etc..

This commit is contained in:
Chris Ross 2014-10-15 15:17:58 -07:00
parent dc600a636a
commit 114d834876
12 changed files with 267 additions and 17 deletions

View File

@ -31,9 +31,8 @@ namespace Microsoft.AspNet.FeatureModel
return GetInterface(null);
}
public object GetInterface(Type type)
public object GetInterface([NotNull] Type type)
{
if (type == null) throw new ArgumentNullException("type");
object feature;
if (_featureByFeatureType.TryGetValue(type, out feature))
{
@ -63,10 +62,8 @@ namespace Microsoft.AspNet.FeatureModel
return null;
}
void SetInterface(Type type, object feature)
void SetInterface([NotNull] Type type, object feature)
{
if (type == null) throw new ArgumentNullException("type");
if (feature == null)
{
Remove(type);
@ -153,16 +150,13 @@ namespace Microsoft.AspNet.FeatureModel
get { return false; }
}
public bool ContainsKey(Type key)
public bool ContainsKey([NotNull] Type key)
{
if (key == null) throw new ArgumentNullException("key");
return GetInterface(key) != null;
}
public void Add(Type key, object value)
public void Add([NotNull] Type key, [NotNull] object value)
{
if (key == null) throw new ArgumentNullException("key");
if (value == null) throw new ArgumentNullException("value");
if (ContainsKey(key))
{
throw new ArgumentException();
@ -170,10 +164,8 @@ namespace Microsoft.AspNet.FeatureModel
SetInterface(key, value);
}
public bool Remove(Type key)
public bool Remove([NotNull] Type key)
{
if (key == null) throw new ArgumentNullException("key");
lock (_containerSync)
{
Type priorFeatureType;
@ -188,7 +180,7 @@ namespace Microsoft.AspNet.FeatureModel
}
}
public bool TryGetValue(Type key, out object value)
public bool TryGetValue([NotNull] Type key, out object value)
{
value = GetInterface(key);
return value != null;

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.FeatureModel
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
internal sealed class NotNullAttribute : Attribute
{
}
}

View File

@ -1,6 +1,8 @@
{
"version": "1.0.0-*",
"dependencies": {},
"dependencies": {
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-*"
},
"frameworks": {
"aspnet50": {},
"aspnetcore50": {

View File

@ -0,0 +1,60 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
namespace Microsoft.AspNet.Http
{
public static class SessionCollectionExtensions
{
public static void SetInt(this ISessionCollection session, string key, int value)
{
var bytes = new byte[]
{
(byte)(value >> 24),
(byte)(0xFF & (value >> 16)),
(byte)(0xFF & (value >> 8)),
(byte)(0xFF & value)
};
session.Set(key, bytes);
}
public static int? GetInt(this ISessionCollection session, string key)
{
var data = session.Get(key);
if (data == null || data.Length < 4)
{
return null;
}
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
}
public static void SetString(this ISessionCollection session, string key, string value)
{
session.Set(key, Encoding.UTF8.GetBytes(value));
}
public static string GetString(this ISessionCollection session, string key)
{
var data = session.Get(key);
if (data == null)
{
return null;
}
return Encoding.UTF8.GetString(data);
}
public static byte[] Get(this ISessionCollection session, string key)
{
byte[] value = null;
session.TryGetValue(key, out value);
return value;
}
public static void Set(this ISessionCollection session, string key, byte[] value)
{
session.Set(key, new ArraySegment<byte>(value));
}
}
}

View File

@ -9,8 +9,6 @@
},
"aspnetcore50" : {
"dependencies": {
"System.Reflection": "4.0.10-beta-*",
"System.Reflection.Extensions": "4.0.0-beta-*",
"System.Reflection.TypeExtensions": "4.0.0-beta-*",
"System.Runtime": "4.0.20-beta-*"
}

View File

@ -28,6 +28,8 @@ namespace Microsoft.AspNet.Http
public abstract CancellationToken RequestAborted { get; }
public abstract ISessionCollection Session { get; }
public abstract bool IsWebSocketRequest { get; }
public abstract IList<string> WebSocketRequestedProtocols { get; }

View File

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
namespace Microsoft.AspNet.Http
{
public interface ISessionCollection : IEnumerable<KeyValuePair<string, byte[]>>
{
byte[] this[string key] { get; set; }
bool TryGetValue(string key, out byte[] value);
void Set(string key, ArraySegment<byte> value);
void Remove(string key);
void Clear();
}
}

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.HttpFeature
{
[AssemblyNeutral]
public interface ISession
{
void Load();
void Commit();
bool TryGetValue(string key, out byte[] value);
void Set(string key, ArraySegment<byte> value);
void Remove(string key);
void Clear();
IEnumerable<string> Keys { get; }
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.HttpFeature
{
[AssemblyNeutral]
public interface ISessionFactory
{
bool IsAvailable { get; }
ISession Create();
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.HttpFeature
{
// TODO: Is there any reason not to flatten the Factory down into the Feature?
[AssemblyNeutral]
public interface ISessionFeature
{
ISessionFactory Factory { get; set; }
ISession Session { get; set; }
}
}

View File

@ -0,0 +1,75 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
namespace Microsoft.AspNet.PipelineCore.Collections
{
public class SessionCollection : ISessionCollection
{
private readonly ISession _session;
public SessionCollection(ISession session)
{
_session = session;
}
public byte[] this[string key]
{
get
{
byte[] value;
TryGetValue(key, out value);
return value;
}
set
{
if (value == null)
{
Remove(key);
}
else
{
Set(key, new ArraySegment<byte>(value));
}
}
}
public bool TryGetValue(string key, out byte[] value)
{
return _session.TryGetValue(key, out value);
}
public void Set(string key, ArraySegment<byte> value)
{
_session.Set(key, value);
}
public void Remove(string key)
{
_session.Remove(key);
}
public void Clear()
{
_session.Clear();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<KeyValuePair<string, byte[]>> GetEnumerator()
{
foreach (var key in _session.Keys)
{
yield return new KeyValuePair<string, byte[]>(key, this[key]);
}
}
}
}

View File

@ -14,6 +14,7 @@ using Microsoft.AspNet.Http.Infrastructure;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.PipelineCore.Collections;
using Microsoft.AspNet.PipelineCore.Infrastructure;
using Microsoft.AspNet.PipelineCore.Security;
@ -31,6 +32,7 @@ namespace Microsoft.AspNet.PipelineCore
private FeatureReference<IHttpAuthenticationFeature> _authentication;
private FeatureReference<IHttpRequestLifetimeFeature> _lifetime;
private FeatureReference<IHttpWebSocketFeature> _webSockets;
private FeatureReference<ISessionFeature> _session;
private IFeatureCollection _features;
public DefaultHttpContext()
@ -51,6 +53,7 @@ namespace Microsoft.AspNet.PipelineCore
_authentication = FeatureReference<IHttpAuthenticationFeature>.Default;
_lifetime = FeatureReference<IHttpRequestLifetimeFeature>.Default;
_webSockets = FeatureReference<IHttpWebSocketFeature>.Default;
_session = FeatureReference<ISessionFeature>.Default;
}
IItemsFeature ItemsFeature
@ -78,6 +81,11 @@ namespace Microsoft.AspNet.PipelineCore
get { return _webSockets.Fetch(_features); }
}
private ISessionFeature SessionFeature
{
get { return _session.Fetch(_features); }
}
public override HttpRequest Request { get { return _request; } }
public override HttpResponse Response { get { return _response; } }
@ -129,6 +137,27 @@ namespace Microsoft.AspNet.PipelineCore
}
}
public override ISessionCollection Session
{
get
{
var feature = SessionFeature;
if (feature == null)
{
throw new InvalidOperationException("Session has not been configured for this application or request.");
}
if (feature.Session == null)
{
if (feature.Factory == null)
{
throw new InvalidOperationException("No ISessionFactory available to create the ISession.");
}
feature.Session = feature.Factory.Create();
}
return new SessionCollection(feature.Session);
}
}
public override bool IsWebSocketRequest
{
get