-
Notifications
You must be signed in to change notification settings - Fork 933
/
Copy pathSessionFactoryObjectFactory.cs
147 lines (136 loc) · 5.68 KB
/
SessionFactoryObjectFactory.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace NHibernate.Impl
{
/// <summary>
/// Resolves <see cref="ISessionFactory"/> lookups and deserialization.
/// </summary>
/// <remarks>
/// <para>
/// This is used heavily be Deserialization. Currently a SessionFactory is not really serialized.
/// All that is serialized is it's name and uid. During Deserializaiton the serialized SessionFactory
/// is converted to the one contained in this object. So if you are serializing across AppDomains
/// you should make sure that "name" is specified for the SessionFactory in the hbm.xml file and that the
/// other AppDomain has a configured SessionFactory with the same name. If
/// you are serializing in the same AppDomain then there will be no problem because the uid will
/// be in this object.
/// </para>
/// </remarks>
public static class SessionFactoryObjectFactory
{
private static readonly INHibernateLogger log;
private static readonly IDictionary<string, ISessionFactory> Instances = new Dictionary<string, ISessionFactory>();
private static readonly IDictionary<string, ISessionFactory> NamedInstances = new Dictionary<string, ISessionFactory>();
/// <summary></summary>
static SessionFactoryObjectFactory()
{
log = NHibernateLogger.For(typeof(SessionFactoryObjectFactory));
log.Debug("initializing class SessionFactoryObjectFactory");
}
/// <summary>
/// Adds an Instance of the SessionFactory to the local "cache".
/// </summary>
/// <param name="uid">The identifier of the ISessionFactory.</param>
/// <param name="name">The name of the ISessionFactory.</param>
/// <param name="instance">The ISessionFactory.</param>
/// <param name="properties">The configured properties for the ISessionFactory.</param>
[MethodImpl(MethodImplOptions.Synchronized)]
public static void AddInstance(string uid, string name, ISessionFactory instance, IDictionary<string, string> properties)
{
if (log.IsDebugEnabled())
{
string nameMsg = ((!string.IsNullOrEmpty(name)) ? name : "unnamed");
log.Debug("registered: {0}({1})", uid, nameMsg);
}
Instances[uid] = instance;
if (!string.IsNullOrEmpty(name))
{
log.Info("Factory name:{0}", name);
NamedInstances[name] = instance;
}
else
{
log.Info("no name configured");
}
}
/// <summary>
/// Removes the Instance of the SessionFactory from the local "cache".
/// </summary>
/// <param name="uid">The identifier of the ISessionFactory.</param>
/// <param name="name">The name of the ISessionFactory.</param>
/// <param name="properties">The configured properties for the ISessionFactory.</param>
[MethodImpl(MethodImplOptions.Synchronized)]
public static void RemoveInstance(string uid, string name, IDictionary<string, string> properties)
{
if (!string.IsNullOrEmpty(name))
{
log.Info("unbinding factory: {0}", name);
NamedInstances.Remove(name);
}
Instances.Remove(uid);
}
/// <summary>
/// Get an instance of the SessionFactory from the local "cache" identified by name if it
/// exists, otherwise run the provided factory and return its result.
/// </summary>
/// <param name="name">The name of the ISessionFactory.</param>
/// <param name="instanceBuilder">The ISessionFactory factory to use if the instance is not
/// found.</param>
/// <returns>An instantiated ISessionFactory.</returns>
/// <remarks>
/// <para>It is the caller responsibility to ensure <paramref name="instanceBuilder"/>
/// will add and yield a session factory of the requested <paramref name="name"/>.</para>
/// <para>If the session factory instantiation is performed concurrently outside of a
/// <c>GetOrAddNamedInstance</c> call, this method may yield an instance of it still being
/// built, which may lead to threading issues.</para>
/// </remarks>
[MethodImpl(MethodImplOptions.Synchronized)]
public static ISessionFactory GetOrBuildNamedInstance(string name, Func<ISessionFactory> instanceBuilder)
{
if (instanceBuilder == null)
throw new ArgumentNullException(nameof(instanceBuilder));
if (NamedInstances.TryGetValue(name, out var factory))
return factory;
return instanceBuilder();
}
/// <summary>
/// Returns a Named Instance of the SessionFactory from the local "cache" identified by name.
/// </summary>
/// <param name="name">The name of the ISessionFactory.</param>
/// <returns>An ISessionFactory if found, <see langword="null" /> otherwise.</returns>
/// <remarks>If the session factory instantiation is performed concurrently, this method
/// may yield an instance of it still being built, which may lead to threading issues.
/// Use <see cref="GetOrBuildNamedInstance(string, Func{ISessionFactory})" /> to get or
/// built the session factory in such case.</remarks>
[MethodImpl(MethodImplOptions.Synchronized)]
public static ISessionFactory GetNamedInstance(string name)
{
log.Debug("lookup: name={0}", name);
ISessionFactory factory;
bool found = NamedInstances.TryGetValue(name, out factory);
if (!found)
{
log.Warn("Not found: {0}", name);
}
return factory;
}
/// <summary>
/// Returns an Instance of the SessionFactory from the local "cache" identified by UUID.
/// </summary>
/// <param name="uid">The identifier of the ISessionFactory.</param>
/// <returns>An ISessionFactory if found, <see langword="null" /> otherwise.</returns>
[MethodImpl(MethodImplOptions.Synchronized)]
public static ISessionFactory GetInstance(string uid)
{
log.Debug("lookup: uid={0}", uid);
ISessionFactory factory;
bool found = Instances.TryGetValue(uid, out factory);
if (!found)
{
log.Warn("Not found: {0}", uid);
}
return factory;
}
}
}