forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMapBasedSessionContext.cs
67 lines (60 loc) · 1.84 KB
/
MapBasedSessionContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System.Collections;
using System.Collections.Concurrent;
using NHibernate.Engine;
namespace NHibernate.Context
{
public abstract class MapBasedSessionContext : CurrentSessionContext
{
private readonly ISessionFactoryImplementor _factory;
// Must be static, different instances of MapBasedSessionContext may have to yield the same map.
private static readonly object _locker = new object();
protected MapBasedSessionContext(ISessionFactoryImplementor factory)
{
_factory = factory;
}
/// <summary>
/// Gets or sets the currently bound session.
/// </summary>
protected override ISession Session
{
get
{
ISession value = null;
GetConcreteMap()?.TryGetValue(_factory, out value);
// We want null if no value was there, no need to explicitly handle false outcome of TryGetValue.
return value;
}
set
{
var map = GetConcreteMap();
if (map == null)
{
// Double check locking. Cannot use a Lazy<T> for such a semantic: the map can be bound
// to some execution context through SetMap/GetMap, a Lazy<T> would defeat those methods purpose.
lock (_locker)
{
map = GetConcreteMap();
if (map == null)
{
map = new ConcurrentDictionary<ISessionFactoryImplementor, ISession>();
SetMap(map);
}
}
}
map[_factory] = value;
}
}
private ConcurrentDictionary<ISessionFactoryImplementor, ISession> GetConcreteMap()
{
return (ConcurrentDictionary<ISessionFactoryImplementor, ISession>)GetMap();
}
/// <summary>
/// Get the dictionary mapping session factory to its current session. Yield <c>null</c> if none have been set.
/// </summary>
protected abstract IDictionary GetMap();
/// <summary>
/// Set the map mapping session factory to its current session.
/// </summary>
protected abstract void SetMap(IDictionary value);
}
}