Permalink
Browse files

Created ISession with SessionFactory provider using ICacheClient.

Can now share the same session between MVC and ServiceStack with ISession
Can now RequestContext.Get<IHttpResponse>()
Can now Filter = (req, res, dto) => req.TryResolve<IDependency>();
  • Loading branch information...
1 parent 4678449 commit 490cbffd5e0253e3154da4207d40ace4867eb6b6 @mythz mythz committed Dec 16, 2011
Showing with 359 additions and 392 deletions.
  1. +1 −1 NuGet/ServiceStack.Common/servicestack.common.nuspec
  2. +1 −1 NuGet/ServiceStack.Host.AspNet/servicestack.host.aspnet.nuspec
  3. +14 −0 NuGet/ServiceStack.Host.Mvc/content/App_Start/ControllerBase.cs.pp
  4. +2 −0 NuGet/ServiceStack.Host.Mvc/content/App_Start/ServiceStackFramework.cs.pp
  5. +1 −1 NuGet/ServiceStack.Host.Mvc/servicestack.host.mvc.nuspec
  6. +1 −1 NuGet/ServiceStack/servicestack.nuspec
  7. +1 −1 src/RazorEngine/RazorHandler.cs
  8. +31 −0 src/ServiceStack.Interfaces/CacheAccess/ISession.cs
  9. +18 −0 src/ServiceStack.Interfaces/CacheAccess/ISessionFactory.cs
  10. +2 −0 src/ServiceStack.Interfaces/ServiceHost/IHttpRequest.cs
  11. +2 −0 src/ServiceStack.Interfaces/ServiceStack.Interfaces.csproj
  12. +22 −0 src/ServiceStack.ServiceInterface/ServiceBase.cs
  13. +1 −0 src/ServiceStack.ServiceInterface/ServiceStack.ServiceInterface.csproj
  14. +61 −0 src/ServiceStack.ServiceInterface/SessionFactory.cs
  15. +19 −6 src/ServiceStack.ServiceInterface/SessionFeature.cs
  16. +5 −0 src/ServiceStack.ServiceInterface/Testing/MockHttpRequest.cs
  17. +1 −1 src/ServiceStack.ServiceInterface/Testing/TestBase.cs
  18. +1 −1 src/ServiceStack/Properties/AssemblyInfo.cs
  19. +8 −4 src/ServiceStack/ServiceHost/HttpRequestContext.cs
  20. +2 −2 src/ServiceStack/WebHost.EndPoints/EndpointHost.cs
  21. +13 −3 src/ServiceStack/WebHost.EndPoints/Extensions/HttpListenerRequestWrapper.cs
  22. +13 −3 src/ServiceStack/WebHost.EndPoints/Extensions/HttpRequestWrapper.cs
  23. +1 −1 src/ServiceStack/WebHost.EndPoints/Extensions/HttpResponseWrapper.cs
  24. +1 −1 src/ServiceStack/WebHost.EndPoints/Extensions/IHttpResponseExtensions.cs
  25. +3 −3 src/ServiceStack/WebHost.EndPoints/GenericHandler.cs
  26. +1 −1 src/ServiceStack/WebHost.EndPoints/JsvSyncReplyHandler.cs
  27. +3 −3 src/ServiceStack/WebHost.EndPoints/RestHandler.cs
  28. +4 −3 src/ServiceStack/WebHost.EndPoints/Support/EndpointHandlerBase.cs
  29. +1 −1 src/ServiceStack/WebHost.EndPoints/Support/Markdown/MarkdownHandler.cs
  30. +5 −0 src/ServiceStack/WebHost.EndPoints/Support/Mocks/HttpRequestMock.cs
  31. +2 −2 src/ServiceStack/WebHost.EndPoints/Support/SoapHandler.cs
  32. +3 −4 tests/ServiceStack.Common.Tests/ReflectionUtilTests.cs
  33. +0 −4 tests/ServiceStack.Common.Tests/ServiceStack.Common.Tests.csproj
  34. +0 −226 tests/ServiceStack.Common.Tests/Support/InvokeSimpleCommandsTests.cs
  35. +0 −37 tests/ServiceStack.Common.Tests/Support/ModelWithFieldsOfDifferentTypes.cs
  36. +0 −27 tests/ServiceStack.Common.Tests/Support/ModelWithOnlyStringFields.cs
  37. +0 −31 tests/ServiceStack.Common.Tests/Support/PathInfoTests.cs
  38. +1 −1 tests/ServiceStack.ServiceHost.Tests/Formats/ViewTests.cs
  39. +22 −17 tests/ServiceStack.ServiceHost.Tests/Routes/SimpleRestServices.cs
  40. +5 −0 tests/ServiceStack.ServiceHost.Tests/ServiceStackHandlerUrlTests.cs
  41. +1 −1 tests/ServiceStack.WebHost.Endpoints.Tests/HttpResultTests.cs
  42. +1 −1 tests/ServiceStack.WebHost.Endpoints.Tests/Support/EndpointHandlerBaseTests.cs
  43. +5 −0 tests/ServiceStack.WebHost.IntegrationTests/Global.asax.cs
  44. +2 −0 tests/ServiceStack.WebHost.IntegrationTests/ServiceStack.WebHost.IntegrationTests.csproj
  45. +65 −0 tests/ServiceStack.WebHost.IntegrationTests/Services/SessionService.cs
  46. +10 −0 tests/ServiceStack.WebHost.IntegrationTests/Tests/SessionTests.cs
  47. +3 −3 tests/ServiceStack.WebHost.IntegrationTests/Web.config
@@ -2,7 +2,7 @@
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>ServiceStack.Common</id>
- <version>3.1.3</version>
+ <version>3.1.6</version>
<authors>Demis Bellot</authors>
<owners>Demis Bellot</owners>
<summary>Opensource .NET and Mono REST Web Services framework</summary>
@@ -2,7 +2,7 @@
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>ServiceStack.Host.AspNet</id>
- <version>3.1.5</version>
+ <version>3.1.6</version>
<authors>Demis Bellot</authors>
<owners>Demis Bellot</owners>
<summary>Opensource .NET and Mono REST Web Services framework</summary>
@@ -10,6 +10,20 @@
public abstract class ControllerBase : Controller
{
public ICacheClient Cache { get; set; }
+ public ISessionFactory SessionFactory { get; set; }
+
+ private ISession session;
+ public ISession Session
+ {
+ get
+ {
+ return session ?? (session =
+ SessionFactory.GetOrCreateSession(
+ new ServiceStack.WebHost.Endpoints.Extensions.HttpRequestWrapper(null, System.Web.HttpContext.Current.Request),
+ new ServiceStack.WebHost.Endpoints.Extensions.HttpResponseWrapper(System.Web.HttpContext.Current.Response)
+ ));
+ }
+ }
protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
@@ -48,6 +48,8 @@
//Register In-Memory Cache provider.
//For Distributed Cache Providers Use: PooledRedisClientManager, BasicRedisClientManager or see: https://github.com/ServiceStack/ServiceStack/wiki/Caching
container.Register<ICacheClient>(new MemoryCacheClient());
+ container.Register<ISessionFactory>(c =>
+ new SessionFactory(c.Resolve<ICacheClient>()));
//Set MVC to use the same Funq IOC as ServiceStack
ControllerBuilder.Current.SetControllerFactory(new FunqControllerFactory(container));
@@ -2,7 +2,7 @@
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>ServiceStack.Host.Mvc</id>
- <version>3.1.5</version>
+ <version>3.1.6</version>
<authors>Demis Bellot</authors>
<owners>Demis Bellot</owners>
<summary>Opensource .NET and Mono REST Web Services framework</summary>
@@ -2,7 +2,7 @@
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>ServiceStack</id>
- <version>3.1.3</version>
+ <version>3.1.6</version>
<authors>Demis Bellot</authors>
<owners>Demis Bellot</owners>
<summary>Opensource .NET and Mono REST Web Services framework</summary>
@@ -40,7 +40,7 @@ public override object CreateRequest(IHttpRequest request, string operationName)
return null;
}
- public override object GetResponse(IHttpRequest httpReq, object request)
+ public override object GetResponse(IHttpRequest httpReq, IHttpResponse httpRes, object request)
{
return null;
}
@@ -0,0 +1,31 @@
+namespace ServiceStack.CacheAccess
+{
+ /// <summary>
+ /// A Users Session
+ /// </summary>
+ public interface ISession
+ {
+ /// <summary>
+ /// Store any object at key
+ /// </summary>
+ /// <param name="key"></param>
+ /// <returns></returns>
+ object this[string key] { get; set; }
+
+ /// <summary>
+ /// Set a typed value at key
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ void Set<T>(string key, T value);
+
+ /// <summary>
+ /// Get a typed value at key
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="key"></param>
+ /// <returns></returns>
+ T Get<T>(string key);
+ }
+}
@@ -0,0 +1,18 @@
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.CacheAccess
+{
+ /// <summary>
+ /// Retrieves a User Session
+ /// </summary>
+ public interface ISessionFactory
+ {
+ /// <summary>
+ /// Gets the session for this request, creates one if it doesn't exist.
+ /// </summary>
+ /// <param name="httpReq"></param>
+ /// <param name="httpRes"></param>
+ /// <returns></returns>
+ ISession GetOrCreateSession(IHttpRequest httpReq, IHttpResponse httpRes);
+ }
+}
@@ -10,6 +10,8 @@ public interface IHttpRequest
{
object OriginalRequest { get; }
+ T TryResolve<T>();
+
string OperationName { get; }
string ContentType { get; }
@@ -83,6 +83,8 @@
<Compile Include="CacheAccess\IMemcachedClient.cs" />
<Compile Include="CacheAccess\IPersistenceProviderCache.cs" />
<Compile Include="CacheAccess\IPersistenceProviderCacheFactory.cs" />
+ <Compile Include="CacheAccess\ISession.cs" />
+ <Compile Include="CacheAccess\ISessionFactory.cs" />
<Compile Include="Configuration\IFactoryProvider.cs" />
<Compile Include="Configuration\IContainerAdapter.cs" />
<Compile Include="Configuration\IResourceManager.cs" />
@@ -1,5 +1,8 @@
using System;
using System.Net;
+using System.Web;
+using ServiceStack.CacheAccess;
+using ServiceStack.CacheAccess.Providers;
using ServiceStack.Common;
using ServiceStack.Common.Utils;
using ServiceStack.Common.Web;
@@ -10,6 +13,7 @@
using ServiceStack.ServiceInterface.ServiceModel;
using ServiceStack.Text;
using ServiceStack.WebHost.Endpoints;
+using ServiceStack.WebHost.Endpoints.Extensions;
namespace ServiceStack.ServiceInterface
{
@@ -73,6 +77,24 @@ public virtual IAppHost AppHost
public IRequestContext RequestContext { get; set; }
+ public ISessionFactory SessionFactory { get; set; }
+
+ private ISession session;
+ public ISession Session
+ {
+ get
+ {
+ if (SessionFactory == null)
+ SessionFactory = new SessionFactory(this.GetCacheClient());
+
+ return session ?? (session =
+ SessionFactory.GetOrCreateSession(
+ RequestContext.Get<IHttpRequest>(),
+ RequestContext.Get<IHttpResponse>()
+ ));
+ }
+ }
+
/// <summary>
/// Resolve an alternate Web Service from ServiceStack's IOC container.
/// </summary>
@@ -132,6 +132,7 @@
<Compile Include="Deprecated.Session\PublicAndPrivateClientSessions.cs" />
<Compile Include="Deprecated.Session\UserSession.cs" />
<Compile Include="ServiceRoutesExtension.cs" />
+ <Compile Include="SessionFactory.cs" />
<Compile Include="SessionFeature.cs" />
<Compile Include="Testing\BasicAppHost.cs" />
<Compile Include="Testing\MockHttpRequest.cs">
@@ -0,0 +1,61 @@
+using System;
+using ServiceStack.CacheAccess;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.ServiceInterface
+{
+ public class SessionFactory : ISessionFactory
+ {
+ private readonly ICacheClient cacheClient;
+
+ public SessionFactory(ICacheClient cacheClient)
+ {
+ this.cacheClient = cacheClient;
+ }
+
+ public class SessionCacheClient : ISession
+ {
+ private readonly ICacheClient cacheClient;
+ private string prefixNs;
+
+ public SessionCacheClient(ICacheClient cacheClient, string sessionId)
+ {
+ this.cacheClient = cacheClient;
+ this.prefixNs = "sess:" + sessionId + ":";
+ }
+
+ public object this[string key]
+ {
+ get
+ {
+ return cacheClient.Get<object>(this.prefixNs + key);
+ }
+ set
+ {
+ JsWriter.WriteDynamic(() =>
+ cacheClient.Set(this.prefixNs + key, value));
+ }
+ }
+
+ public void Set<T>(string key, T value)
+ {
+ cacheClient.Set(this.prefixNs + key, value);
+ }
+
+ public T Get<T>(string key)
+ {
+ return cacheClient.Get<T>(this.prefixNs + key);
+ }
+ }
+
+ public ISession GetOrCreateSession(IHttpRequest httpReq, IHttpResponse httpRes)
+ {
+ var sessionId = httpReq.GetCookieValue(SessionFeature.PermanentSessionId)
+ ?? httpRes.CreatePermanentSessionId(httpReq);
+
+ return new SessionCacheClient(cacheClient, sessionId);
+ }
+ }
+}
@@ -21,15 +21,11 @@ public static void Init(IAppHost appHost)
appHost.RequestFilters.Add((req, res, dto) => {
if (req.GetCookieValue(SessionId) == null)
{
- var sessionId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
- res.SetSessionCookie(SessionId, sessionId);
- req.Items[SessionId] = sessionId;
+ res.CreateTemporarySessionId(req);
}
if (req.GetCookieValue(PermanentSessionId) == null)
{
- var permanentId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
- res.SetPermanentCookie(PermanentSessionId, permanentId);
- req.Items[PermanentSessionId] = permanentId;
+ res.CreatePermanentSessionId(req);
}
});
}
@@ -43,5 +39,22 @@ public static string GetTemporarySessionId(this IHttpRequest httpReq)
{
return httpReq.GetItemOrCookie(SessionId);
}
+
+ public static string CreatePermanentSessionId(this IHttpResponse res, IHttpRequest req)
+ {
+ var sessionId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
+ res.SetPermanentCookie(PermanentSessionId, sessionId);
+ req.Items[PermanentSessionId] = sessionId;
+ return sessionId;
+ }
+
+ public static string CreateTemporarySessionId(this IHttpResponse res, IHttpRequest req)
+ {
+ var sessionId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
+ res.SetSessionCookie(SessionId, sessionId);
+ req.Items[SessionId] = sessionId;
+ return sessionId;
+ }
+
}
}
@@ -37,6 +37,11 @@ public object OriginalRequest
get { return null; }
}
+ public T TryResolve<T>()
+ {
+ throw new NotImplementedException();
+ }
+
public string OperationName { get; set; }
public string ContentType { get; set; }
public string HttpMethod { get; set; }
@@ -332,7 +332,7 @@ public TResponse ExecutePath<TResponse>(string httpMethod, string pathInfo, obje
);
var request = httpHandler.CreateRequest(httpReq, httpHandler.RequestName);
- var response = httpHandler.GetResponse(httpReq, request);
+ var response = httpHandler.GetResponse(httpReq, null, request);
var httpRes = response as IHttpResult;
if (httpRes != null)
@@ -33,5 +33,5 @@
// 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("3.1.3.*")]
+[assembly: AssemblyVersion("3.1.6.*")]
//[assembly: AssemblyFileVersion("1.0.*")]
@@ -11,6 +11,7 @@ public class HttpRequestContext
: IRequestContext
{
private readonly IHttpRequest httpReq;
+ private readonly IHttpResponse httpRes;
public HttpRequestContext(object dto)
: this(dto, null)
@@ -22,15 +23,16 @@ public HttpRequestContext(object dto, EndpointAttributes endpointAttributes)
{
}
- public HttpRequestContext(IHttpRequest httpReq, object dto)
- : this(httpReq, dto, EndpointAttributes.None)
+ public HttpRequestContext(IHttpRequest httpReq, IHttpResponse httpRes, object dto)
+ : this(httpReq, httpRes, dto, EndpointAttributes.None)
{
}
- public HttpRequestContext(IHttpRequest httpReq, object dto, EndpointAttributes endpointAttributes)
+ public HttpRequestContext(IHttpRequest httpReq, IHttpResponse httpRes, object dto, EndpointAttributes endpointAttributes)
: this(dto, endpointAttributes, null)
{
this.httpReq = httpReq;
+ this.httpRes = httpRes;
if (this.httpReq != null)
{
this.Files = httpReq.Files;
@@ -83,7 +85,9 @@ public string ResponseContentType
public T Get<T>() where T : class
{
if (typeof(T) == typeof(IHttpRequest))
- return (T) this.httpReq;
+ return (T)this.httpReq;
+ if (typeof(T) == typeof(IHttpResponse))
+ return (T)this.httpRes;
var isDto = this.Dto as T;
return isDto ?? (this.Factory != null ? this.Factory.Resolve<T>() : null);
@@ -188,12 +188,12 @@ public static void SetOperationTypes(ServiceOperations operationTypes, ServiceOp
AllServiceOperations = allOperationTypes;
}
- internal static object ExecuteService(object request, EndpointAttributes endpointAttributes, IHttpRequest httpReq)
+ internal static object ExecuteService(object request, EndpointAttributes endpointAttributes, IHttpRequest httpReq, IHttpResponse httpRes)
{
using (Profiler.Current.Step("Execute Service"))
{
return config.ServiceController.Execute(request,
- new HttpRequestContext(httpReq, request, endpointAttributes));
+ new HttpRequestContext(httpReq, httpRes, request, endpointAttributes));
}
}
Oops, something went wrong.

0 comments on commit 490cbff

Please sign in to comment.