Skip to content

Commit 0c2f139

Browse files
fixup! Clean-up IObjectsFactory usages
Do an alternate cleanup for session context
1 parent 3f74b75 commit 0c2f139

14 files changed

+94
-103
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using NHibernate.Cfg;
2+
using NHibernate.Context;
3+
using NHibernate.Engine;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.ConnectionTest
7+
{
8+
[TestFixture]
9+
public class CustomCurrentSessionTest : ConnectionManagementTestCase
10+
{
11+
protected override ISession GetSessionUnderTest()
12+
{
13+
var session = OpenSession();
14+
CustomContext.Session = session;
15+
return session;
16+
}
17+
18+
protected override void Configure(Configuration configuration)
19+
{
20+
base.Configure(cfg);
21+
cfg.SetProperty(Environment.CurrentSessionContextClass, typeof(CustomContext).AssemblyQualifiedName);
22+
}
23+
24+
protected override void Release(ISession session)
25+
{
26+
CustomContext.Session = null;
27+
base.Release(session);
28+
}
29+
30+
[Test]
31+
public void ContextIsSetup()
32+
{
33+
Assert.That(Sfi.CurrentSessionContext, Is.InstanceOf<CustomContext>());
34+
Assert.That(
35+
((CustomContext) Sfi.CurrentSessionContext).Factory,
36+
Is.SameAs(((DebugSessionFactory) Sfi).ActualFactory));
37+
}
38+
}
39+
40+
public class CustomContext : ICurrentSessionContextWithFactory
41+
{
42+
internal ISessionFactoryImplementor Factory;
43+
internal static ISession Session;
44+
45+
public ISession CurrentSession()
46+
{
47+
return Session;
48+
}
49+
50+
public void SetFactory(ISessionFactoryImplementor factory)
51+
{
52+
Factory = factory;
53+
}
54+
}
55+
}

src/NHibernate.Test/ConnectionTest/MapBasedSessionContextFixture.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Threading;
33
using NHibernate.Cfg;
44
using NHibernate.Context;
5+
using NHibernate.Engine;
56
using NUnit.Framework;
67

78
namespace NHibernate.Test.ConnectionTest
@@ -58,6 +59,8 @@ public void MapContextThreadSafety()
5859

5960
public class TestableMapBasedSessionContext : MapBasedSessionContext
6061
{
62+
public TestableMapBasedSessionContext(ISessionFactoryImplementor factory) : base(factory) { }
63+
6164
// Context is the app with such implementation. Just for the test case.
6265
internal static IDictionary _map;
6366

src/NHibernate.Test/ConnectionTest/ThreadLocalCurrentSessionTest.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using NHibernate.Cfg;
22
using NHibernate.Context;
3+
using NHibernate.Engine;
34
using NUnit.Framework;
45

56
namespace NHibernate.Test.ConnectionTest
@@ -70,7 +71,8 @@ public class TestableThreadLocalContext : ThreadLocalSessionContext
7071
{
7172
private static TestableThreadLocalContext me;
7273

73-
public TestableThreadLocalContext()
74+
public TestableThreadLocalContext(ISessionFactoryImplementor factory)
75+
: base(factory)
7476
{
7577
me = this;
7678
}

src/NHibernate/Async/Context/ThreadLocalSessionContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
using System;
1212
using System.Collections.Generic;
1313

14+
using NHibernate;
1415
using NHibernate.Engine;
1516

1617
namespace NHibernate.Context
1718
{
1819
using System.Threading.Tasks;
1920
using System.Threading;
20-
public partial class ThreadLocalSessionContext : ICurrentSessionContextWithFactory
21+
public partial class ThreadLocalSessionContext : ICurrentSessionContext
2122
{
2223

2324
private static async Task CleanupAnyOrphanedSessionAsync(ISessionFactory factory, CancellationToken cancellationToken)

src/NHibernate/Context/AsyncLocalSessionContext.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ public class AsyncLocalSessionContext : CurrentSessionContext
2121
{
2222
private readonly AsyncLocal<ISession> _session = new AsyncLocal<ISession>();
2323

24-
// Since v5.2
25-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
24+
// Constructor signature required for dynamic invocation code.
2625
public AsyncLocalSessionContext(ISessionFactoryImplementor factory) { }
2726

28-
public AsyncLocalSessionContext() { }
29-
3027
protected override ISession Session
3128
{
3229
get => _session.Value;

src/NHibernate/Context/CallSessionContext.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,10 @@ public class CallSessionContext : MapBasedSessionContext
2727
private static readonly AsyncLocal<IDictionary> SessionFactoryMap = new AsyncLocal<IDictionary>();
2828
#endif
2929

30-
// Since v5.2
31-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
3230
public CallSessionContext(ISessionFactoryImplementor factory) : base(factory)
3331
{
3432
}
3533

36-
public CallSessionContext() { }
37-
3834
/// <summary>
3935
/// The key is the session factory and the value is the bound session.
4036
/// </summary>

src/NHibernate/Context/CurrentSessionContext.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace NHibernate.Context
1616
/// through <see cref="ISessionFactory.GetCurrentSession()"/> calls.
1717
/// </remarks>
1818
[Serializable]
19-
public abstract class CurrentSessionContext : ICurrentSessionContextWithFactory
19+
public abstract class CurrentSessionContext : ICurrentSessionContext
2020
{
2121
/// <summary> Gets or sets the currently bound session. </summary>
2222
protected abstract ISession Session { get; set; }
@@ -37,12 +37,6 @@ public virtual ISession CurrentSession()
3737
return Session;
3838
}
3939

40-
/// <inheritdoc />
41-
public virtual void SetFactory(ISessionFactoryImplementor factory)
42-
{
43-
// No-op by default.
44-
}
45-
4640
/// <summary>
4741
/// Binds the specified session to the current context.
4842
/// </summary>

src/NHibernate/Context/ICurrentSessionContext.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using NHibernate.Bytecode;
12
using NHibernate.Engine;
23

34
namespace NHibernate.Context
@@ -11,7 +12,8 @@ namespace NHibernate.Context
1112
/// Implementations should adhere to the following:
1213
/// <list type="bullet">
1314
/// <item><description>contain a constructor accepting a single argument of type
14-
/// <see cref="ISessionFactoryImplementor" /></description></item>
15+
/// <see cref="ISessionFactoryImplementor" />, or implement
16+
/// <see cref="ICurrentSessionContextWithFactory"/></description></item>
1517
/// <item><description>should be thread safe</description></item>
1618
/// <item><description>should be fully serializable</description></item>
1719
/// </list>
@@ -42,9 +44,10 @@ public interface ICurrentSessionContext
4244
ISession CurrentSession();
4345
}
4446

45-
// 6.0 TODO: merge into ICurrentSessionContext
4647
/// <summary>
47-
/// Transitional interface for <see cref="ICurrentSessionContext"/>.
48+
/// An <see cref="ICurrentSessionContext"/> allowing to set its session factory. Implementing
49+
/// this interface allows the <see cref="IObjectsFactory"/> to be used for instantiating the
50+
/// session context.
4851
/// </summary>
4952
public interface ICurrentSessionContextWithFactory : ICurrentSessionContext
5053
{

src/NHibernate/Context/MapBasedSessionContext.cs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using System.Collections;
32
using System.Collections.Concurrent;
43
using NHibernate.Engine;
@@ -7,28 +6,16 @@ namespace NHibernate.Context
76
{
87
public abstract class MapBasedSessionContext : CurrentSessionContext
98
{
10-
private ISessionFactoryImplementor _factory;
9+
private readonly ISessionFactoryImplementor _factory;
1110

1211
// Must be static, different instances of MapBasedSessionContext may have to yield the same map.
1312
private static readonly object _locker = new object();
1413

15-
// Since v5.2
16-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
1714
protected MapBasedSessionContext(ISessionFactoryImplementor factory)
1815
{
1916
_factory = factory;
2017
}
2118

22-
protected MapBasedSessionContext() { }
23-
24-
/// <inheritdoc />
25-
public override void SetFactory(ISessionFactoryImplementor factory)
26-
{
27-
if (_factory != null)
28-
throw new InvalidOperationException("The factory has already been set");
29-
_factory = factory;
30-
}
31-
3219
/// <summary>
3320
/// Gets or sets the currently bound session.
3421
/// </summary>

src/NHibernate/Context/ThreadLocalSessionContext.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33

4+
using NHibernate;
45
using NHibernate.Engine;
56

67
namespace NHibernate.Context
@@ -30,25 +31,21 @@ namespace NHibernate.Context
3031
/// <para>The cleanup on transaction end is indeed not implemented.</para>
3132
/// </summary>
3233
[Serializable]
33-
public partial class ThreadLocalSessionContext : ICurrentSessionContextWithFactory
34+
public partial class ThreadLocalSessionContext : ICurrentSessionContext
3435
{
3536
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(ThreadLocalSessionContext));
3637

3738
[ThreadStatic]
3839
protected static IDictionary<ISessionFactory, ISession> context;
3940

40-
protected ISessionFactoryImplementor factory;
41+
protected readonly ISessionFactoryImplementor factory;
4142

4243

43-
// Since v5.2
44-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
4544
public ThreadLocalSessionContext(ISessionFactoryImplementor factory)
4645
{
4746
this.factory = factory;
4847
}
4948

50-
public ThreadLocalSessionContext() { }
51-
5249
#region ICurrentSessionContext Members
5350

5451
public ISession CurrentSession()
@@ -69,14 +66,6 @@ public ISession CurrentSession()
6966
return current;
7067
}
7168

72-
/// <inheritdoc />
73-
public void SetFactory(ISessionFactoryImplementor factory)
74-
{
75-
if (this.factory != null)
76-
throw new InvalidOperationException("The factory has already been set");
77-
this.factory = factory;
78-
}
79-
8069
#endregion
8170

8271
private static void CleanupAnyOrphanedSession(ISessionFactory factory)

src/NHibernate/Context/ThreadStaticSessionContext.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,8 @@ public class ThreadStaticSessionContext : MapBasedSessionContext
1414
[ThreadStatic]
1515
private static IDictionary _map;
1616

17-
// Since v5.2
18-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
1917
public ThreadStaticSessionContext(ISessionFactoryImplementor factory) : base (factory) { }
2018

21-
public ThreadStaticSessionContext() { }
22-
2319
protected override IDictionary GetMap()
2420
{
2521
return _map;

src/NHibernate/Context/WcfOperationSessionContext.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@ namespace NHibernate.Context
1212
/// </summary>
1313
public class WcfOperationSessionContext : MapBasedSessionContext
1414
{
15-
// Since v5.2
16-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
1715
public WcfOperationSessionContext(ISessionFactoryImplementor factory) : base(factory) {}
1816

19-
public WcfOperationSessionContext() { }
20-
2117
private static WcfStateExtension WcfOperationState
2218
{
2319
get

src/NHibernate/Context/WebSessionContext.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@ public class WebSessionContext : MapBasedSessionContext
1313
{
1414
private const string SessionFactoryMapKey = "NHibernate.Context.WebSessionContext.SessionFactoryMapKey";
1515

16-
// Since v5.2
17-
[Obsolete("This constructor has no more usages and will be removed in a future version")]
1816
public WebSessionContext(ISessionFactoryImplementor factory) : base(factory) {}
1917

20-
public WebSessionContext() { }
21-
2218
protected override IDictionary GetMap()
2319
{
2420
return ReflectiveHttpContext.HttpContextCurrentItems[SessionFactoryMapKey] as IDictionary;

src/NHibernate/Impl/SessionFactoryImpl.cs

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,65 +1261,41 @@ private IDictionary<string, HibernateException> CheckNamedQueries()
12611261

12621262
private ICurrentSessionContext BuildCurrentSessionContext()
12631263
{
1264-
var impl = PropertiesHelper.GetString(Environment.CurrentSessionContextClass, properties, null);
1264+
string impl = PropertiesHelper.GetString(Environment.CurrentSessionContextClass, properties, null);
12651265

1266-
ICurrentSessionContextWithFactory context;
12671266
switch (impl)
12681267
{
12691268
case null:
12701269
return null;
12711270
case "async_local":
1272-
context = new AsyncLocalSessionContext();
1273-
break;
1271+
return new AsyncLocalSessionContext(this);
12741272
case "call":
1275-
context = new CallSessionContext();
1276-
break;
1273+
return new CallSessionContext(this);
12771274
case "thread_static":
1278-
context = new ThreadStaticSessionContext();
1279-
break;
1275+
return new ThreadStaticSessionContext(this);
12801276
case "web":
1281-
context = new WebSessionContext();
1282-
break;
1277+
return new WebSessionContext(this);
12831278
case "wcf_operation":
1284-
context = new WcfOperationSessionContext();
1285-
break;
1286-
default:
1287-
context = null;
1288-
break;
1279+
return new WcfOperationSessionContext(this);
12891280
}
12901281

1291-
if (context == null)
1282+
try
12921283
{
1293-
try
1284+
var implClass = ReflectHelper.ClassForName(impl);
1285+
if (!typeof(ICurrentSessionContextWithFactory).IsAssignableFrom(implClass))
12941286
{
1295-
var implClass = ReflectHelper.ClassForName(impl);
1296-
if (!typeof(ICurrentSessionContextWithFactory).IsAssignableFrom(implClass))
1297-
{
1298-
log.Warn(
1299-
"{0} implementations should implement {1}.{2} and a parameter-less constructor. Instantiating " +
1300-
"them with a constructor taking an {3} is obsolete. Concrete type not implementing {1}: {4}",
1301-
nameof(ICurrentSessionContext),
1302-
nameof(ICurrentSessionContextWithFactory),
1303-
nameof(ICurrentSessionContextWithFactory.SetFactory),
1304-
nameof(ISessionFactoryImplementor),
1305-
implClass);
1306-
return
1307-
#pragma warning disable 618
1308-
(ICurrentSessionContext) Environment.ObjectsFactory.CreateInstance(implClass, this);
1309-
#pragma warning restore 618
1310-
}
1311-
1312-
context = (ICurrentSessionContextWithFactory) Environment.ObjectsFactory.CreateInstance(implClass);
1287+
return (ICurrentSessionContext) Activator.CreateInstance(implClass, this);
13131288
}
1314-
catch (Exception e)
1315-
{
1316-
log.Error(e, "Unable to construct current session context [{0}]", impl);
1317-
return null;
1318-
}
1319-
}
13201289

1321-
context.SetFactory(this);
1322-
return context;
1290+
var context = (ICurrentSessionContextWithFactory) Environment.ObjectsFactory.CreateInstance(implClass);
1291+
context.SetFactory(this);
1292+
return context;
1293+
}
1294+
catch (Exception e)
1295+
{
1296+
log.Error(e, "Unable to construct current session context [{0}]", impl);
1297+
return null;
1298+
}
13231299
}
13241300

13251301
#region NHibernate specific

0 commit comments

Comments
 (0)