From: <fab...@us...> - 2010-08-05 12:20:16
|
Revision: 5113 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5113&view=rev Author: fabiomaulo Date: 2010-08-05 12:20:09 +0000 (Thu, 05 Aug 2010) Log Message: ----------- Partial fix of NH-2263 2 step (thanks to Patrick Earl) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Context/ManagedWebSessionContext.cs trunk/nhibernate/src/NHibernate/Context/WebSessionContext.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Context/ReflectiveHttpContext.cs Modified: trunk/nhibernate/src/NHibernate/Context/ManagedWebSessionContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Context/ManagedWebSessionContext.cs 2010-08-05 11:06:46 UTC (rev 5112) +++ trunk/nhibernate/src/NHibernate/Context/ManagedWebSessionContext.cs 2010-08-05 12:20:09 UTC (rev 5113) @@ -1,13 +1,12 @@ using System; using System.Collections; -using System.Web; using NHibernate.Engine; namespace NHibernate.Context { /// <summary> /// Provides a <see cref="ISessionFactory.GetCurrentSession()">current session</see> - /// for each <see cref="System.Web.HttpContext"/>. + /// for each System.Web.HttpContext. /// Works only with Web Applications. /// </summary> [Serializable] @@ -23,7 +22,7 @@ public ISession CurrentSession() { - ISession currentSession = GetExistingSession(HttpContext.Current, factory); + ISession currentSession = GetExistingSession(ReflectiveHttpContext.HttpContextCurrentGetter(), factory); if (currentSession == null) { throw new HibernateException("No session bound to the current HttpContext"); @@ -33,20 +32,20 @@ #region Static API - public static void Bind(HttpContext context, ISession session) + public static void Bind(object httpContext, ISession session) { - GetSessionMap(context, true)[((ISessionImplementor) session).Factory] = session; + GetSessionMap(httpContext, true)[((ISessionImplementor) session).Factory] = session; } - public static bool HasBind(HttpContext context, ISessionFactory factory) + public static bool HasBind(object httpContext, ISessionFactory factory) { - return GetExistingSession(context, factory) != null; + return GetExistingSession(httpContext, factory) != null; } - public static ISession Unbind(HttpContext context, ISessionFactory factory) + public static ISession Unbind(object httpContext, ISessionFactory factory) { ISession result = null; - IDictionary sessionMap = GetSessionMap(context, false); + IDictionary sessionMap = GetSessionMap(httpContext, false); if (sessionMap != null) { result = sessionMap[factory] as ISession; @@ -57,9 +56,9 @@ #endregion - private static ISession GetExistingSession(HttpContext context, ISessionFactory factory) + private static ISession GetExistingSession(object httpContext, ISessionFactory factory) { - IDictionary sessionMap = GetSessionMap(context, false); + IDictionary sessionMap = GetSessionMap(httpContext, false); if (sessionMap == null) { return null; @@ -68,15 +67,16 @@ return sessionMap[factory] as ISession; } - private static IDictionary GetSessionMap(HttpContext context, bool create) + private static IDictionary GetSessionMap(object httpContext, bool create) { - IDictionary map = context.Items[SessionFactoryMapKey] as IDictionary; + IDictionary httpContextItems = ReflectiveHttpContext.HttpContextItemsGetter(httpContext); + var map = httpContextItems[SessionFactoryMapKey] as IDictionary; if (map == null && create) { map = new Hashtable(); - context.Items[SessionFactoryMapKey] = map; + httpContextItems[SessionFactoryMapKey] = map; } return map; } } -} +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Context/ReflectiveHttpContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Context/ReflectiveHttpContext.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Context/ReflectiveHttpContext.cs 2010-08-05 12:20:09 UTC (rev 5113) @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using System.Linq.Expressions; +using System.Reflection; + +namespace NHibernate.Context +{ + /// <summary> + /// This class allows access to the HttpContext without referring to HttpContext at compile time. + /// The accessors are cached as delegates for performance. + /// </summary> + public static class ReflectiveHttpContext + { + static ReflectiveHttpContext() + { + CreateCurrentHttpContextGetter(); + CreateHttpContextItemsGetter(); + } + + public static Func<object> HttpContextCurrentGetter { get; private set; } + + public static Func<object, IDictionary> HttpContextItemsGetter { get; private set; } + + public static IDictionary HttpContextCurrentItems + { + get { return HttpContextItemsGetter(HttpContextCurrentGetter()); } + } + + private static System.Type HttpContextType + { + get { return System.Type.GetType("System.Web.HttpContext, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); } + } + + private static void CreateCurrentHttpContextGetter() + { + PropertyInfo currentProperty = HttpContextType.GetProperty("Current", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); + Expression propertyExpression = Expression.Property(null, currentProperty); + Expression convertedExpression = Expression.Convert(propertyExpression, typeof (object)); + HttpContextCurrentGetter = (Func<object>) Expression.Lambda(convertedExpression).Compile(); + } + + private static void CreateHttpContextItemsGetter() + { + ParameterExpression contextParam = Expression.Parameter(typeof (object), "context"); + Expression convertedParam = Expression.Convert(contextParam, HttpContextType); + Expression itemsProperty = Expression.Property(convertedParam, "Items"); + HttpContextItemsGetter = (Func<object, IDictionary>) Expression.Lambda(itemsProperty, contextParam).Compile(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Context/WebSessionContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Context/WebSessionContext.cs 2010-08-05 11:06:46 UTC (rev 5112) +++ trunk/nhibernate/src/NHibernate/Context/WebSessionContext.cs 2010-08-05 12:20:09 UTC (rev 5113) @@ -1,32 +1,28 @@ using System; using System.Collections; -using System.Web; - using NHibernate.Engine; namespace NHibernate.Context { /// <summary> /// Provides a <see cref="ISessionFactory.GetCurrentSession()">current session</see> - /// for each <see cref="System.Web.HttpContext"/>. Works only with web applications. + /// for each System.Web.HttpContext. Works only with web applications. /// </summary> [Serializable] public class WebSessionContext : MapBasedSessionContext { private const string SessionFactoryMapKey = "NHibernate.Context.WebSessionContext.SessionFactoryMapKey"; - public WebSessionContext(ISessionFactoryImplementor factory) : base(factory) - { - } + public WebSessionContext(ISessionFactoryImplementor factory) : base(factory) {} protected override IDictionary GetMap() { - return HttpContext.Current.Items[SessionFactoryMapKey] as IDictionary; + return ReflectiveHttpContext.HttpContextCurrentItems[SessionFactoryMapKey] as IDictionary; } protected override void SetMap(IDictionary value) { - HttpContext.Current.Items[SessionFactoryMapKey] = value; + ReflectiveHttpContext.HttpContextCurrentItems[SessionFactoryMapKey] = value; } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-08-05 11:06:46 UTC (rev 5112) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-08-05 12:20:09 UTC (rev 5113) @@ -53,7 +53,6 @@ <RequiredTargetFramework>3.0</RequiredTargetFramework> </Reference> <Reference Include="System.Transactions" /> - <Reference Include="System.Web" /> <Reference Include="System.Xml" /> <Reference Include="Antlr3.Runtime, Version=3.1.0.39271, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7"> <SpecificVersion>False</SpecificVersion> @@ -564,6 +563,7 @@ </Compile> <Compile Include="Cfg\XmlHbmBinding\TypeBinder.cs" /> <Compile Include="Cfg\XmlHbmBinding\ValuePropertyBinder.cs" /> + <Compile Include="Context\ReflectiveHttpContext.cs" /> <Compile Include="Context\WcfOperationSessionContext.cs" /> <Compile Include="Criterion\GroupedProjection.cs" /> <Compile Include="Criterion\IPropertyProjection.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |