1+ using System ;
12using System . Collections . Generic ;
23using System . Runtime . CompilerServices ;
34
@@ -78,16 +79,46 @@ public static void RemoveInstance(string uid, string name, IDictionary<string, s
7879 }
7980
8081 /// <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.
8284 /// </summary>
8385 /// <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>
8488 /// <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>
85116 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
86117 public static ISessionFactory GetNamedInstance ( string name )
87118 {
88119 log . Debug ( "lookup: name={0}" , name ) ;
89120 ISessionFactory factory ;
90- bool found = NamedInstances . TryGetValue ( name , out factory ) ;
121+ bool found = NamedInstances . TryGetValue ( name , out factory ) ;
91122 if ( ! found )
92123 {
93124 log . Warn ( "Not found: {0}" , name ) ;
@@ -99,7 +130,7 @@ public static ISessionFactory GetNamedInstance(string name)
99130 /// Returns an Instance of the SessionFactory from the local "cache" identified by UUID.
100131 /// </summary>
101132 /// <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>
103134 [ MethodImpl ( MethodImplOptions . Synchronized ) ]
104135 public static ISessionFactory GetInstance ( string uid )
105136 {
0 commit comments