@@ -15,12 +15,14 @@ namespace Autofac.Pooling;
1515internal sealed class PoolActivator < TLimit > : IInstanceActivator
1616 where TLimit : class
1717{
18- private readonly Service _pooledInstanceService ;
19- private readonly IPooledRegistrationPolicy < TLimit > _policy ;
20- private readonly DefaultObjectPoolProvider _poolProvider ;
18+ private readonly Service ? _pooledInstanceService ;
19+ private readonly IPooledRegistrationPolicy < TLimit > ? _policy ;
20+ private readonly DefaultObjectPoolProvider ? _poolProvider ;
21+ private readonly Func < IComponentContext , IPooledRegistrationPolicy < TLimit > > ? _policyFactory ;
2122
2223 /// <summary>
23- /// Initializes a new instance of the <see cref="PoolActivator{TLimit}"/> class.
24+ /// Initializes a new instance of the <see cref="PoolActivator{TLimit}"/> class
25+ /// using the default <see cref="DefaultObjectPoolProvider"/>.
2426 /// </summary>
2527 /// <param name="pooledInstanceService">The service used to resolve new instances of the pooled registration.</param>
2628 /// <param name="policy">The pool policy.</param>
@@ -34,6 +36,23 @@ public PoolActivator(Service pooledInstanceService, IPooledRegistrationPolicy<TL
3436 } ;
3537 }
3638
39+ /// <summary>
40+ /// Initializes a new instance of the <see cref="PoolActivator{TLimit}"/> class
41+ /// using a factory function to create the <see cref="IPooledRegistrationPolicy{TLimit}"/> at resolve time.
42+ /// The default <see cref="DefaultObjectPoolProvider"/> will create the backing pool.
43+ /// </summary>
44+ /// <param name="pooledInstanceService">The service used to resolve new instances of the pooled registration.</param>
45+ /// <param name="policyFactory">
46+ /// A factory that returns the <see cref="IPooledRegistrationPolicy{TLimit}"/> to use.
47+ /// Invoked during resolve, so the <see cref="IComponentContext"/> is available
48+ /// for resolving dependencies.
49+ /// </param>
50+ public PoolActivator ( Service pooledInstanceService , Func < IComponentContext , IPooledRegistrationPolicy < TLimit > > policyFactory )
51+ {
52+ _pooledInstanceService = pooledInstanceService ;
53+ _policyFactory = policyFactory ?? throw new ArgumentNullException ( nameof ( policyFactory ) ) ;
54+ }
55+
3756 /// <inheritdoc/>
3857 public Type LimitType { get ; } = typeof ( TLimit ) ;
3958
@@ -42,15 +61,31 @@ public void ConfigurePipeline(IComponentRegistryServices componentRegistryServic
4261 {
4362 pipelineBuilder . Use ( PipelinePhase . Activation , ( context , next ) =>
4463 {
45- // Get a reference to the actual lifetime scope.
46- var scope = context . Resolve < ILifetimeScope > ( ) ;
64+ if ( _policyFactory is not null )
65+ {
66+ // Custom policy factory: resolve the strategy at resolve time, then create DefaultObjectPool.
67+ var policy = _policyFactory ( context ) ;
68+ var poolProvider = new DefaultObjectPoolProvider
69+ {
70+ MaximumRetained = policy . MaximumRetained ,
71+ } ;
72+ var scope = context . Resolve < ILifetimeScope > ( ) ;
73+ var poolPolicy = new AutofacPooledObjectPolicy < TLimit > ( _pooledInstanceService ! , scope , policy ) ;
74+ var pool = poolProvider . Create ( poolPolicy ) ;
75+ context . Instance = new PooledInstanceContext < TLimit > ( pool , policy ) ;
76+ }
77+ else
78+ {
79+ // Default path: use DefaultObjectPoolProvider + AutofacPooledObjectPolicy.
80+ var scope = context . Resolve < ILifetimeScope > ( ) ;
4781
48- var poolPolicy = new AutofacPooledObjectPolicy < TLimit > ( _pooledInstanceService , scope , _policy ) ;
82+ var poolPolicy = new AutofacPooledObjectPolicy < TLimit > ( _pooledInstanceService ! , scope , _policy ! ) ;
4983
50- // The pool provider will create a disposable pool if the TLimit implements IDisposable.
51- var pool = _poolProvider . Create ( poolPolicy ) ;
84+ // The pool provider will create a disposable pool if the TLimit implements IDisposable.
85+ var pool = _poolProvider ! . Create ( poolPolicy ) ;
5286
53- context . Instance = pool ;
87+ context . Instance = pool ;
88+ }
5489 } ) ;
5590 }
5691
0 commit comments