@@ -9,6 +9,7 @@ namespace AutofacContrib.NSubstitute
9
9
{
10
10
public class AutoSubstituteBuilder
11
11
{
12
+ private readonly Dictionary < Type , object > _customDataManager ;
12
13
private readonly Dictionary < Type , object > _substituteForRegistrations ;
13
14
private readonly List < Action < IComponentContext > > _afterBuildActions ;
14
15
private readonly ContainerBuilder _builder ;
@@ -20,18 +21,20 @@ public class AutoSubstituteBuilder
20
21
public AutoSubstituteBuilder ( )
21
22
{
22
23
_substituteForRegistrations = new Dictionary < Type , object > ( ) ;
24
+ _customDataManager = new Dictionary < Type , object > ( ) ;
23
25
_afterBuildActions = new List < Action < IComponentContext > > ( ) ;
24
26
_builder = new ContainerBuilder ( ) ;
25
27
_options = new AutoSubstituteOptions ( ) ;
26
28
}
27
-
29
+
28
30
/// <summary>
29
31
/// Creates a new instance that allows linking to the previous instance for derived builders.
30
32
/// </summary>
31
33
/// <param name="other">A <see cref="AutoSubstituteBuilder"/> that should be connected to this instance</param>
32
- private protected AutoSubstituteBuilder ( AutoSubstituteBuilder other )
34
+ protected AutoSubstituteBuilder ( AutoSubstituteBuilder other )
33
35
{
34
36
_substituteForRegistrations = other . _substituteForRegistrations ;
37
+ _customDataManager = other . _customDataManager ;
35
38
_afterBuildActions = other . _afterBuildActions ;
36
39
_builder = other . _builder ;
37
40
_options = other . _options ;
@@ -277,15 +280,53 @@ private SubstituteForBuilder<TService> CreateSubstituteForBuilder<TService>(Func
277
280
return builder ;
278
281
}
279
282
280
- private protected IProvidedValue < TService > CreateProvidedValue < TService > ( Func < IComponentContext , TService > factory )
283
+ /// <summary>
284
+ /// Registers a callback for about <see cref="Build"/> is called.
285
+ /// </summary>
286
+ /// <param name="callback">Callback to call.</param>
287
+ protected void RegisterBuildCallback ( Action < IComponentContext > callback )
288
+ => _afterBuildActions . Add ( callback ) ;
289
+
290
+ /// <summary>
291
+ /// Creates a delayed provided value with the given factory method.
292
+ /// </summary>
293
+ /// <typeparam name="TService">Service to expose for the provided value.</typeparam>
294
+ /// <param name="factory">Factory to create value.</param>
295
+ /// <returns>A provided value.</returns>
296
+ protected IProvidedValue < TService > CreateProvidedValue < TService > ( Func < IComponentContext , TService > factory )
281
297
{
282
298
var value = new ProvidedValue < TService > ( factory ) ;
283
299
284
- _afterBuildActions . Add ( c => value . SetComponentContext ( c ) ) ;
300
+ RegisterBuildCallback ( c => value . SetComponentContext ( c ) ) ;
285
301
286
302
return value ;
287
303
}
288
304
305
+ /// <summary>
306
+ /// Retrieves storage of item that needs to be persisted across multiple calls to configuration methods.
307
+ /// Some methods will wrap the builder into a new object, so this ensures that data used in one builder
308
+ /// can be accessed later on.
309
+ ///
310
+ /// Since the data is keyed by type, it is recommended to use a custom data type to hold the data if it
311
+ /// is a well-known type.
312
+ /// </summary>
313
+ /// <typeparam name="T">Type of custom data.</typeparam>
314
+ /// <param name="factory">Factory to create data.</param>
315
+ /// <returns>A cached instance of the data, or a new instance if not already available.</returns>
316
+ protected T GetCustomData < T > ( Func < T > factory )
317
+ {
318
+ if ( _customDataManager . TryGetValue ( typeof ( T ) , out var result ) )
319
+ {
320
+ return ( T ) result ;
321
+ }
322
+
323
+ var created = factory ( ) ;
324
+
325
+ _customDataManager . Add ( typeof ( T ) , created ) ;
326
+
327
+ return created ;
328
+ }
329
+
289
330
private class ProvidedValue < T > : IProvidedValue < T >
290
331
{
291
332
private readonly Func < IComponentContext , T > _factory ;
0 commit comments