1
+ using System ;
1
2
using System . Collections . Generic ;
2
3
using System . Runtime . CompilerServices ;
3
4
@@ -78,16 +79,46 @@ public static void RemoveInstance(string uid, string name, IDictionary<string, s
78
79
}
79
80
80
81
/// <summary>
81
- /// Returns a Named Instance of the SessionFactory from the local "cache" identified by name.
82
+ /// Get an instance of the SessionFactory from the local "cache" identified by name if it
83
+ /// exists, otherwise run the provided factory and return its result.
82
84
/// </summary>
83
85
/// <param name="name">The name of the ISessionFactory.</param>
86
+ /// <param name="instanceBuilder">The ISessionFactory factory to use if the instance is not
87
+ /// found.</param>
84
88
/// <returns>An instantiated ISessionFactory.</returns>
89
+ /// <remarks>
90
+ /// <para>It is the caller responsibility to ensure <paramref name="instanceBuilder"/>
91
+ /// will add and yield a session factory of the requested <paramref name="name"/>.</para>
92
+ /// <para>If the session factory instantiation is performed concurrently outside of a
93
+ /// <c>GetOrAddNamedInstance</c> call, this method may yield an instance of it still being
94
+ /// built, which may lead to threading issues.</para>
95
+ /// </remarks>
96
+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
97
+ public static ISessionFactory GetOrBuildNamedInstance ( string name , Func < ISessionFactory > instanceBuilder )
98
+ {
99
+ if ( instanceBuilder == null )
100
+ throw new ArgumentNullException ( nameof ( instanceBuilder ) ) ;
101
+
102
+ if ( NamedInstances . TryGetValue ( name , out var factory ) )
103
+ return factory ;
104
+ return instanceBuilder ( ) ;
105
+ }
106
+
107
+ /// <summary>
108
+ /// Returns a Named Instance of the SessionFactory from the local "cache" identified by name.
109
+ /// </summary>
110
+ /// <param name="name">The name of the ISessionFactory.</param>
111
+ /// <returns>An ISessionFactory if found, <see langword="null" /> otherwise.</returns>
112
+ /// <remarks>If the session factory instantiation is performed concurrently, this method
113
+ /// may yield an instance of it still being built, which may lead to threading issues.
114
+ /// Use <see cref="GetOrBuildNamedInstance(string, Func{ISessionFactory})" /> to get or
115
+ /// built the session factory in such case.</remarks>
85
116
[ MethodImpl ( MethodImplOptions . Synchronized ) ]
86
117
public static ISessionFactory GetNamedInstance ( string name )
87
118
{
88
119
log . Debug ( "lookup: name={0}" , name ) ;
89
120
ISessionFactory factory ;
90
- bool found = NamedInstances . TryGetValue ( name , out factory ) ;
121
+ bool found = NamedInstances . TryGetValue ( name , out factory ) ;
91
122
if ( ! found )
92
123
{
93
124
log . Warn ( "Not found: {0}" , name ) ;
@@ -99,7 +130,7 @@ public static ISessionFactory GetNamedInstance(string name)
99
130
/// Returns an Instance of the SessionFactory from the local "cache" identified by UUID.
100
131
/// </summary>
101
132
/// <param name="uid">The identifier of the ISessionFactory.</param>
102
- /// <returns>An instantiated ISessionFactory.</returns>
133
+ /// <returns>An ISessionFactory if found, <see langword="null" /> otherwise .</returns>
103
134
[ MethodImpl ( MethodImplOptions . Synchronized ) ]
104
135
public static ISessionFactory GetInstance ( string uid )
105
136
{
0 commit comments