Updating with work in progress

This commit is contained in:
Louis DeJardin 2014-01-23 14:53:22 -08:00
parent bdf69b0d0c
commit 27ff7762e9
47 changed files with 672 additions and 315 deletions

View File

@ -7,14 +7,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Abstractio
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.FeatureModel", "src\Microsoft.AspNet.FeatureModel\Microsoft.AspNet.FeatureModel.csproj", "{A780873E-09F9-4E44-AE06-AF00C4E88E1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.HttpEnvironment", "src\Microsoft.AspNet.HttpEnvironment\Microsoft.AspNet.HttpEnvironment.csproj", "{46D69EC9-7096-49D8-A184-A9BB5B2419A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.HttpFeature", "src\Microsoft.AspNet.HttpFeature\Microsoft.AspNet.HttpFeature.csproj", "{42309978-0661-41D8-8654-39453265C5F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.PipelineCore", "src\Microsoft.AspNet.PipelineCore\Microsoft.AspNet.PipelineCore.csproj", "{A4D3E280-8838-4614-9B99-4874C3CBDF82}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.PipelineCore.Tests", "src\Microsoft.AspNet.PipelineCore.Tests\Microsoft.AspNet.PipelineCore.Tests.csproj", "{86942914-0334-4352-87ED-B971281C74E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.FeatureModel.Tests", "test\Microsoft.AspNet.FeatureModel.Tests\Microsoft.AspNet.FeatureModel.Tests.csproj", "{8C671AE3-1188-499F-A2A2-3A0B117B33CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -29,10 +29,6 @@ Global
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Release|Any CPU.Build.0 = Release|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Release|Any CPU.Build.0 = Release|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -45,6 +41,10 @@ Global
{86942914-0334-4352-87ED-B971281C74E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Release|Any CPU.Build.0 = Release|Any CPU
{8C671AE3-1188-499F-A2A2-3A0B117B33CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C671AE3-1188-499F-A2A2-3A0B117B33CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C671AE3-1188-499F-A2A2-3A0B117B33CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C671AE3-1188-499F-A2A2-3A0B117B33CE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,28 @@
using System;
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpContext : IDisposable
{
// TODO - review IOwinContext for properties
public abstract HttpRequest Request { get; }
public abstract HttpResponse Response { get; }
public abstract void Dispose();
public abstract object GetInterface(Type type);
public abstract void SetInterface(Type type, object instance);
public virtual T GetInterface<T>()
{
return (T)GetInterface(typeof(T));
}
public virtual void SetInterface<T>(T instance)
{
SetInterface(typeof(T), instance);
}
}
}

View File

@ -1,10 +0,0 @@
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpContextBase
{
// TODO - review IOwinContext for properties
public abstract HttpRequestBase Request { get; }
public abstract HttpResponseBase Response { get; }
}
}

View File

@ -3,11 +3,11 @@ using System.IO;
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpRequestBase
public abstract class HttpRequest
{
// TODO - review IOwinRequest for properties
public abstract HttpContextBase HttpContext { get; }
public abstract HttpContext HttpContext { get; }
public abstract Uri Uri { get; }
public abstract PathString PathBase { get; set; }

View File

@ -2,11 +2,11 @@
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpResponseBase
public abstract class HttpResponse
{
// TODO - review IOwinResponse for completeness
public abstract HttpContextBase HttpContext { get; }
public abstract HttpContext HttpContext { get; }
public abstract int StatusCode { get; set; }
public abstract Stream Body { get; set; }
}

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Abstractions
IBuilder New();
RequestDelegate Build();
object GetFeature(Type type);
void SetFeature(Type type, object feature);
object GetItem(Type type);
void SetItem(Type type, object feature);
}
}

View File

@ -36,9 +36,9 @@
<ItemGroup>
<Compile Include="IBuilder.cs" />
<Compile Include="PathString.cs" />
<Compile Include="HttpContextBase.cs" />
<Compile Include="HttpRequestBase.cs" />
<Compile Include="HttpResponseBase.cs" />
<Compile Include="HttpContext.cs" />
<Compile Include="HttpRequest.cs" />
<Compile Include="HttpResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryString.cs" />
<Compile Include="RequestDelegate.cs" />

View File

@ -2,5 +2,5 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Abstractions
{
public delegate Task RequestDelegate(HttpContextBase context);
public delegate Task RequestDelegate(HttpContext context);
}

View File

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class FeatureContainer : IFeatureContainer
{
private readonly IFeatureContainer _defaultFeatures;
private readonly IDictionary<Type, object> _featureByFeatureType = new Dictionary<Type, object>();
private readonly IDictionary<string, Type> _featureTypeByName = new Dictionary<string, Type>();
private readonly object _containerSync = new Object();
private int _containerRevision;
public FeatureContainer()
{
}
public FeatureContainer(IFeatureContainer defaultFeatures)
{
_defaultFeatures = defaultFeatures;
}
public virtual object GetFeature(Type type)
{
object feature;
if (_featureByFeatureType.TryGetValue(type, out feature))
{
return feature;
}
Type actualType;
if (_featureTypeByName.TryGetValue(type.FullName, out actualType))
{
if (_featureByFeatureType.TryGetValue(actualType, out feature))
{
return Converter.Convert(type, actualType, feature);
}
}
return _defaultFeatures != null ? _defaultFeatures.GetFeature(type) : null;
}
public virtual object GetDefaultFeature(Type type)
{
return null;
}
public virtual void SetFeature(Type type, object feature)
{
lock (_containerSync)
{
Type priorFeatureType;
if (_featureTypeByName.TryGetValue(type.FullName, out priorFeatureType))
{
if (priorFeatureType == type)
{
_featureByFeatureType[type] = feature;
}
else
{
_featureTypeByName[type.FullName] = type;
_featureByFeatureType.Remove(priorFeatureType);
_featureByFeatureType.Add(type, feature);
}
}
else
{
_featureTypeByName.Add(type.FullName, type);
_featureByFeatureType.Add(type, feature);
}
Interlocked.Increment(ref _containerRevision);
}
}
public virtual int Revision
{
get { return _containerRevision; }
}
public void Dispose()
{
}
}
}

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
namespace Microsoft.AspNet.FeatureModel
{
public interface IFeatureContainer : IDisposable
{
object GetFeature(Type type);
void SetFeature(Type type, object feature);
//IEnumerable<Type> GetFeatureTypes();
int Revision { get; }
}
}

View File

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
namespace Microsoft.AspNet.FeatureModel
{
public interface IInterfaceDictionary : IDictionary<Type, object>, IDisposable
{
int Revision { get; }
}
}

View File

@ -352,7 +352,7 @@ namespace Microsoft.AspNet.FeatureModel.Implementation
static Type CreateWrapperType(Type targetType, Type sourceType, VerificationSucceededResult result)
{
Dictionary<MethodInfo, MethodInfo> mappings = result.methodMappings;
Type baseType = Assembly.GetExecutingAssembly().GetType("InterfaceMapper.BaseType`1").MakeGenericType(sourceType);
Type baseType = typeof(BaseType<>).MakeGenericType(sourceType);
TypeBuilder tb = modb.DefineType("ProxyType" + counter++ + " wrapping:" + sourceType.Name + " to look like:" + targetType.Name, TypeAttributes.Class, baseType, new Type[] { targetType });
ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { sourceType });
ILGenerator il = cb.GetILGenerator();

View File

@ -0,0 +1,188 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class InterfaceDictionary : IInterfaceDictionary
{
private readonly IInterfaceDictionary _defaults;
private readonly IDictionary<Type, object> _featureByFeatureType = new Dictionary<Type, object>();
private readonly IDictionary<string, Type> _featureTypeByName = new Dictionary<string, Type>();
private readonly object _containerSync = new Object();
private int _containerRevision;
public InterfaceDictionary()
{
}
public InterfaceDictionary(IInterfaceDictionary defaults)
{
_defaults = defaults;
}
public object GetInterface()
{
return GetInterface(null);
}
public object GetInterface(Type type)
{
if (type == null) throw new ArgumentNullException("type");
object feature;
if (_featureByFeatureType.TryGetValue(type, out feature))
{
return feature;
}
Type actualType;
if (_featureTypeByName.TryGetValue(type.FullName, out actualType))
{
if (_featureByFeatureType.TryGetValue(actualType, out feature))
{
if (type.IsInstanceOfType(feature))
{
return feature;
}
return Converter.Convert(type, actualType, feature);
}
}
if (_defaults != null && _defaults.TryGetValue(type, out feature))
{
return feature;
}
return null;
}
void SetInterface(Type type, object feature)
{
if (type == null) throw new ArgumentNullException("type");
if (feature == null) throw new ArgumentNullException("feature");
lock (_containerSync)
{
Type priorFeatureType;
if (_featureTypeByName.TryGetValue(type.FullName, out priorFeatureType))
{
if (priorFeatureType == type)
{
_featureByFeatureType[type] = feature;
}
else
{
_featureTypeByName[type.FullName] = type;
_featureByFeatureType.Remove(priorFeatureType);
_featureByFeatureType.Add(type, feature);
}
}
else
{
_featureTypeByName.Add(type.FullName, type);
_featureByFeatureType.Add(type, feature);
}
Interlocked.Increment(ref _containerRevision);
}
}
public virtual int Revision
{
get { return _containerRevision; }
}
public void Dispose()
{
}
public IEnumerator<KeyValuePair<Type, object>> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(KeyValuePair<Type, object> item)
{
SetInterface(item.Key, item.Value);
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(KeyValuePair<Type, object> item)
{
object value;
return TryGetValue(item.Key, out value) && Equals(item.Value, value);
}
public void CopyTo(KeyValuePair<Type, object>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<Type, object> item)
{
return Contains(item) && Remove(item.Key);
}
public int Count
{
get { throw new NotImplementedException(); }
}
public bool IsReadOnly
{
get { return false; }
}
public bool ContainsKey(Type key)
{
if (key == null) throw new ArgumentNullException("key");
return GetInterface(key) != null;
}
public void Add(Type key, object value)
{
if (key == null) throw new ArgumentNullException("key");
if (value == null) throw new ArgumentNullException("value");
if (ContainsKey(key))
{
throw new ArgumentException();
}
SetInterface(key, value);
}
public bool Remove(Type key)
{
throw new NotImplementedException();
}
public bool TryGetValue(Type key, out object value)
{
throw new NotImplementedException();
}
public object this[Type key]
{
get { return GetInterface(key); }
set { SetInterface(key, value); }
}
public ICollection<Type> Keys
{
get { throw new NotImplementedException(); }
}
public ICollection<object> Values
{
get { throw new NotImplementedException(); }
}
}
}

View File

@ -0,0 +1,133 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class InterfaceObject : IInterfaceDictionary
{
private readonly object _instance;
public InterfaceObject(object instance)
{
_instance = instance;
}
public void Dispose()
{
var disposable = _instance as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
public object GetInterface(Type type)
{
if (type.IsInstanceOfType(_instance))
{
return _instance;
}
foreach (var interfaceType in _instance.GetType().GetInterfaces())
{
if (interfaceType.FullName == type.FullName)
{
return Converter.Convert(interfaceType, type, _instance);
}
}
return null;
}
public void SetInterface(Type type, object feature)
{
throw new NotImplementedException();
}
public int Revision
{
get { return 0; }
}
public IEnumerator<KeyValuePair<Type, object>> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(KeyValuePair<Type, object> item)
{
throw new NotImplementedException();
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(KeyValuePair<Type, object> item)
{
throw new NotImplementedException();
}
public void CopyTo(KeyValuePair<Type, object>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<Type, object> item)
{
throw new NotImplementedException();
}
public int Count
{
get { throw new NotImplementedException(); }
}
public bool IsReadOnly
{
get { throw new NotImplementedException(); }
}
public bool ContainsKey(Type key)
{
throw new NotImplementedException();
}
public void Add(Type key, object value)
{
throw new NotImplementedException();
}
public bool Remove(Type key)
{
throw new NotImplementedException();
}
public bool TryGetValue(Type key, out object value)
{
throw new NotImplementedException();
}
public object this[Type key]
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public ICollection<Type> Keys
{
get { throw new NotImplementedException(); }
}
public ICollection<object> Values
{
get { throw new NotImplementedException(); }
}
}
}

View File

@ -34,10 +34,10 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="IFeatureContainer.cs" />
<Compile Include="FeatureContainer.cs" />
<Compile Include="IInterfaceDictionary.cs" />
<Compile Include="InterfaceDictionary.cs" />
<Compile Include="Implementation\Converter.cs" />
<Compile Include="ObjectFeatureContainer.cs" />
<Compile Include="InterfaceObject.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@ -1,50 +0,0 @@
using System;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class ObjectFeatureContainer : IFeatureContainer
{
private readonly object _instance;
public ObjectFeatureContainer(object instance)
{
_instance = instance;
}
public void Dispose()
{
var disposable = _instance as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
public object GetFeature(Type type)
{
if (type.IsInstanceOfType(_instance))
{
return _instance;
}
foreach (var interfaceType in _instance.GetType().GetInterfaces())
{
if (interfaceType.FullName == type.FullName)
{
return Converter.Convert(interfaceType, type, _instance);
}
}
return null;
}
public void SetFeature(Type type, object feature)
{
throw new NotImplementedException();
}
public int Revision
{
get { return 0; }
}
}
}

View File

@ -2,7 +2,7 @@
namespace Microsoft.AspNet.HttpEnvironment
{
public abstract class HttpEnvironmentBase : FeatureContainer, IHttpEnvironment
public abstract class HttpEnvironment : InterfaceDictionary, IHttpEnvironment
{
}
}

View File

@ -1,10 +0,0 @@
namespace Microsoft.AspNet.HttpEnvironment
{
public static class HttpEnvironmentExtensions
{
public static TFeature GetFeature<TFeature>(this IHttpEnvironment environment) where TFeature : class
{
return (TFeature)environment.GetFeature(typeof(TFeature));
}
}
}

View File

@ -2,7 +2,7 @@
namespace Microsoft.AspNet.HttpEnvironment
{
public interface IHttpEnvironment : IFeatureContainer
public interface IHttpEnvironment : IInterfaceDictionary
{
}
}

View File

@ -34,8 +34,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="HttpEnvironmentBase.cs" />
<Compile Include="HttpEnvironmentExtensions.cs" />
<Compile Include="HttpEnvironment.cs" />
<Compile Include="IHttpEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpApplicationInformation
{

View File

@ -1,4 +1,4 @@
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpBuffering
{

View File

@ -1,6 +1,6 @@
using System.Net;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpConnection
{

View File

@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.IO;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpRequest
public interface IHttpRequestInformation
{
string Protocol { get; set; }
string Scheme { get; set; }

View File

@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.IO;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpResponse
public interface IHttpResponseInformation
{
int StatusCode { get; set; }
string ReasonPhrase { get; set; }

View File

@ -1,7 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpSendFile
{

View File

@ -1,7 +1,7 @@
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpTransportLayerSecurity
{

View File

@ -1,7 +1,7 @@
using System.Net.WebSockets;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature
{
public interface IHttpWebSocketAccept
{

View File

@ -46,8 +46,8 @@
<Compile Include="Security\IHttpAuthentication.cs" />
<Compile Include="IHttpBuffering.cs" />
<Compile Include="IHttpConnection.cs" />
<Compile Include="IHttpRequest.cs" />
<Compile Include="IHttpResponse.cs" />
<Compile Include="IHttpRequestInformation.cs" />
<Compile Include="IHttpResponseInformation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces
namespace Microsoft.AspNet.HttpFeature.Security
{
public interface IAuthenticationChallenge
{

View File

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces.Security
namespace Microsoft.AspNet.HttpFeature.Security
{
public interface IAuthenticationDescription
{

View File

@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Security.Claims;
using Microsoft.AspNet.HttpFeature.Security;
// ReSharper disable once CheckNamespace
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IAuthenticationResult

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Security.Claims;
namespace Microsoft.AspNet.Interfaces.Security
namespace Microsoft.AspNet.HttpFeature.Security
{
public interface IAuthenticationSignIn
{

View File

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces.Security
namespace Microsoft.AspNet.HttpFeature.Security
{
public interface IAuthenticationSignOut
{

View File

@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Interfaces.Security;
namespace Microsoft.AspNet.Interfaces.Security
namespace Microsoft.AspNet.HttpFeature.Security
{
public interface IHttpAuthentication
{

View File

@ -12,8 +12,8 @@ namespace Microsoft.AspNet.PipelineCore.Tests
var builder = new Builder();
var app = builder.Build();
var mockHttpContext = new Moq.Mock<HttpContextBase>();
var mockHttpResponse = new Moq.Mock<HttpResponseBase>();
var mockHttpContext = new Moq.Mock<HttpContext>();
var mockHttpResponse = new Moq.Mock<HttpResponse>();
mockHttpContext.SetupGet(x => x.Response).Returns(mockHttpResponse.Object);
mockHttpResponse.SetupProperty(x => x.StatusCode);

View File

@ -4,45 +4,52 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
using Microsoft.AspNet.PipelineCore.Owin;
namespace Microsoft.AspNet.PipelineCore
{
public class Builder : IBuilder
{
private readonly IFeatureContainer _features;
private readonly IInterfaceDictionary _interfaces;
private readonly IDictionary<string, object> _properties;
private readonly IList<Entry> _components = new List<Entry>();
public Builder()
{
_features = new FeatureModel.FeatureContainer();
_interfaces = new InterfaceDictionary();
_properties = new Dictionary<string, object>();
}
public Builder(IFeatureContainer features)
public Builder(IInterfaceDictionary interfaces, IDictionary<string, object> properties)
{
_features = features;
_interfaces = interfaces;
_properties = properties;
}
public void Dispose()
{
_features.Dispose();
_interfaces.Dispose();
}
public virtual object GetFeature(Type type)
public virtual object GetItem(Type key)
{
return _features.GetFeature(type);
object value;
return _interfaces.TryGetValue(key, out value);
}
public virtual void SetFeature(Type type, object feature)
public virtual void SetItem(Type key, object value)
{
_features.SetFeature(type, feature);
_interfaces[key] = value;
}
public virtual int Revision
public virtual object GetItem(string key)
{
get { return _features.Revision; }
object value;
return _properties.TryGetValue(key, out value);
}
public virtual void SetItem(string key, object value)
{
_properties[key] = value;
}
public IBuilder Use(object middleware, params object[] args)
@ -65,7 +72,7 @@ namespace Microsoft.AspNet.PipelineCore
public IBuilder New()
{
return new Builder(_features);
return new Builder(_interfaces, _properties);
}
public RequestDelegate Build()

View File

@ -0,0 +1,42 @@
using System;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.FeatureModel;
namespace Microsoft.AspNet.PipelineCore
{
public class DefaultHttpContext : HttpContext
{
private readonly IInterfaceDictionary _environment;
private readonly HttpRequest _request;
private readonly HttpResponse _response;
public DefaultHttpContext(IInterfaceDictionary environment)
{
_environment = environment;
_request = new DefaultHttpRequest(this);
_response = new DefaultHttpResponse(this);
}
public override HttpRequest Request { get { return _request; } }
public override HttpResponse Response { get { return _response; } }
public int Revision { get { return _environment.Revision; } }
public override void Dispose()
{
// REVIEW: is this necessary? is the environment "owned" by the context?
_environment.Dispose();
}
public override object GetInterface(Type type)
{
object value;
return _environment.TryGetValue(type, out value) ? value : null;
}
public override void SetInterface(Type type, object instance)
{
_environment[type] = instance;
}
}
}

View File

@ -1,31 +1,31 @@
using System;
using System.IO;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.Interfaces;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpRequest : HttpRequestBase
public class DefaultHttpRequest : HttpRequest
{
private readonly HttpContext _context;
private readonly DefaultHttpContext _context;
private int _revision;
private IHttpRequest _request;
private IHttpRequestInformation _request;
private IHttpConnection _connection;
public HttpRequest(HttpContext context)
public DefaultHttpRequest(DefaultHttpContext context)
{
_context = context;
}
private IHttpRequest IHttpRequest
private IHttpRequestInformation IHttpRequest
{
get { return EnsureCurrent(_request) ?? (_request = _context.GetFeature<IHttpRequest>()); }
get { return EnsureCurrent(_request) ?? (_request = _context.GetInterface<IHttpRequestInformation>()); }
}
private IHttpConnection IHttpConnection
{
get { return EnsureCurrent(_connection) ?? (_connection = _context.GetFeature<IHttpConnection>()); }
get { return EnsureCurrent(_connection) ?? (_connection = _context.GetInterface<IHttpConnection>()); }
}
private T EnsureCurrent<T>(T feature) where T : class
@ -38,7 +38,7 @@ namespace Microsoft.AspNet.PipelineCore
return null;
}
public override HttpContextBase HttpContext { get { return _context; } }
public override HttpContext HttpContext { get { return _context; } }
public override Uri Uri
{

View File

@ -1,24 +1,24 @@
using System.IO;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpResponse : HttpResponseBase
public class DefaultHttpResponse : HttpResponse
{
private readonly HttpContext _context;
private IHttpResponse _response;
private readonly DefaultHttpContext _context;
private IHttpResponseInformation _response;
private int _revision;
public HttpResponse(HttpContext context)
public DefaultHttpResponse(DefaultHttpContext context)
{
_context = context;
}
private IHttpResponse IHttpResponse
private IHttpResponseInformation IHttpResponse
{
get { return EnsureCurrent(_response) ?? (_response = _context.GetFeature<IHttpResponse>()); }
get { return EnsureCurrent(_response) ?? (_response = _context.GetInterface<IHttpResponseInformation>()); }
}
private T EnsureCurrent<T>(T feature) where T : class
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.PipelineCore
return null;
}
public override HttpContextBase HttpContext { get { return _context; } }
public override HttpContext HttpContext { get { return _context; } }
public override int StatusCode
{

View File

@ -1,44 +0,0 @@
using System;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpEnvironment;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpContext : HttpContextBase, IHttpEnvironment
{
private readonly IFeatureContainer _features;
private readonly HttpRequestBase _request;
private readonly HttpResponseBase _response;
public HttpContext(IHttpEnvironment environment)
{
_features = environment;
_request = new HttpRequest(this);
_response = new HttpResponse(this);
}
public override HttpRequestBase Request { get { return _request; } }
public override HttpResponseBase Response { get { return _response; } }
public void Dispose()
{
_features.Dispose();
}
public object GetFeature(Type type)
{
return _features.GetFeature(type);
}
public void SetFeature(Type type, object feature)
{
_features.SetFeature(type, feature);
}
public int Revision
{
get { return _features.Revision; }
}
}
}

View File

@ -36,9 +36,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Builder.cs" />
<Compile Include="HttpContext.cs" />
<Compile Include="HttpRequest.cs" />
<Compile Include="HttpResponse.cs" />
<Compile Include="DefaultHttpContext.cs" />
<Compile Include="DefaultHttpRequest.cs" />
<Compile Include="DefaultHttpResponse.cs" />
<Compile Include="Owin\OwinConstants.cs" />
<Compile Include="Owin\OwinHttpEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -52,10 +52,6 @@
<Project>{4e1520b1-01f4-481b-96a2-24067eaa52fa}</Project>
<Name>Microsoft.AspNet.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.AspNet.HttpEnvironment\Microsoft.AspNet.HttpEnvironment.csproj">
<Project>{46D69EC9-7096-49D8-A184-A9BB5B2419A1}</Project>
<Name>Microsoft.AspNet.HttpEnvironment</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.AspNet.HttpFeature\Microsoft.AspNet.HttpFeature.csproj">
<Project>{42309978-0661-41d8-8654-39453265c5f9}</Project>
<Name>Microsoft.AspNet.HttpFeature</Name>

View File

@ -6,13 +6,13 @@ using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.Interfaces;
namespace Microsoft.AspNet.PipelineCore.Owin
{
public class OwinHttpEnvironment :
IHttpRequest, IHttpResponse, IHttpConnection, IHttpSendFile, IHttpTransportLayerSecurity
IHttpRequestInformation, IHttpResponseInformation, IHttpConnection, IHttpSendFile, IHttpTransportLayerSecurity
{
public IDictionary<string, object> Environment { get; set; }
@ -36,84 +36,84 @@ namespace Microsoft.AspNet.PipelineCore.Owin
Environment[key] = value;
}
string IHttpRequest.Protocol
string IHttpRequestInformation.Protocol
{
get { return Prop<string>("owin.RequestProtocol"); }
set { Prop("owin.RequestProtocol", value); }
}
Uri IHttpRequest.Uri
Uri IHttpRequestInformation.Uri
{
get { throw new NotImplementedException(); }
}
string IHttpRequest.Scheme
string IHttpRequestInformation.Scheme
{
get { return Prop<string>("owin.RequestScheme"); }
set { Prop("owin.RequestScheme", value); }
}
string IHttpRequest.Method
string IHttpRequestInformation.Method
{
get { return Prop<string>("owin.RequestMethod"); }
set { Prop("owin.RequestMethod", value); }
}
string IHttpRequest.PathBase
string IHttpRequestInformation.PathBase
{
get { return Prop<string>("owin.RequestPathBase"); }
set { Prop("owin.RequestPathBase", value); }
}
string IHttpRequest.Path
string IHttpRequestInformation.Path
{
get { return Prop<string>("owin.RequestPath"); }
set { Prop("owin.RequestPath", value); }
}
string IHttpRequest.QueryString
string IHttpRequestInformation.QueryString
{
get { return Prop<string>("owin.RequestQueryString"); }
set { Prop("owin.RequestQueryString", value); }
}
IDictionary<string, string[]> IHttpRequest.Headers
IDictionary<string, string[]> IHttpRequestInformation.Headers
{
get { return Prop<IDictionary<string, string[]>>("owin.RequestHeaders"); }
set { Prop("owin.RequestHeaders", value); }
}
Stream IHttpRequest.Body
Stream IHttpRequestInformation.Body
{
get { return Prop<Stream>("owin.RequestBody"); }
set { Prop("owin.RequestBody", value); }
}
int IHttpResponse.StatusCode
int IHttpResponseInformation.StatusCode
{
get { return Prop<int>("owin.ResponseStatusCode"); }
set { Prop("owin.ResponseStatusCode", value); }
}
string IHttpResponse.ReasonPhrase
string IHttpResponseInformation.ReasonPhrase
{
get { return Prop<string>("owin.ResponseReasonPhrase"); }
set { Prop("owin.ResponseReasonPhrase", value); }
}
IDictionary<string, string[]> IHttpResponse.Headers
IDictionary<string, string[]> IHttpResponseInformation.Headers
{
get { return Prop<IDictionary<string, string[]>>("owin.ResponseHeaders"); }
set { Prop("owin.ResponseHeaders", value); }
}
Stream IHttpResponse.Body
Stream IHttpResponseInformation.Body
{
get { return Prop<Stream>("owin.ResponseBody"); }
set { Prop("owin.ResponseBody", value); }
}
void IHttpResponse.OnSendingHeaders(Action<object> callback, object state)
void IHttpResponseInformation.OnSendingHeaders(Action<object> callback, object state)
{
// TODO:
}

View File

@ -0,0 +1,63 @@
using System;
using Shouldly;
using Xunit;
namespace Microsoft.AspNet.FeatureModel.Tests
{
public interface IThing
{
string Hello();
}
public class Thing : IThing
{
public string Hello()
{
return "World";
}
}
public class InterfaceDictionaryTests
{
[Fact]
public void AddedInterfaceIsReturned()
{
var interfaces = new InterfaceDictionary();
var thing = new Thing();
interfaces.Add(typeof(IThing), thing);
interfaces[typeof(IThing)].ShouldBe(thing);
object thing2;
interfaces.TryGetValue(typeof(IThing), out thing2).ShouldBe(true);
thing2.ShouldBe(thing);
}
[Fact]
public void IndexerAlsoAddsItems()
{
var interfaces = new InterfaceDictionary();
var thing = new Thing();
interfaces[typeof(IThing)] = thing;
interfaces[typeof(IThing)].ShouldBe(thing);
object thing2;
interfaces.TryGetValue(typeof(IThing), out thing2).ShouldBe(true);
thing2.ShouldBe(thing);
}
[Fact]
public void SecondCallToAddThrowsException()
{
var interfaces = new InterfaceDictionary();
var thing = new Thing();
interfaces.Add(typeof(IThing), thing);
Should.Throw<ArgumentException>(() => interfaces.Add(typeof(IThing), thing));
}
}
}

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8C671AE3-1188-499F-A2A2-3A0B117B33CE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.FeatureModel.Tests</RootNamespace>
<AssemblyName>Microsoft.AspNet.FeatureModel.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Shouldly">
<HintPath>..\..\packages\Shouldly.1.1.1.1\lib\35\Shouldly.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="xunit">
<HintPath>..\..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNet.FeatureModel\Microsoft.AspNet.FeatureModel.csproj">
<Project>{A780873E-09F9-4E44-AE06-AF00C4E88E1E}</Project>
<Name>Microsoft.AspNet.FeatureModel</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.FeatureModel.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.FeatureModel.Tests")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a780740b-8831-40e0-a084-489d738dfef5")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Shouldly" version="1.1.1.1" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
</packages>