-
Notifications
You must be signed in to change notification settings - Fork 0
Named Pools
Run several independently configured pools for one item type — a small read pool and a large write pool over the same connection. This guide covers registering named pools, resolving them through the pool factory, per-pool configuration, and binding a pool to a dedicated client type. The registration extensions are listed in Dependency injection.
Register the pool factory once, then a named pool per configuration:
services.AddPoolFactory<DbConnection>();
services.AddNamedPool<DbConnection>("ReadPool", configuration, options =>
{
options.MinSize = 5;
options.MaxSize = 20;
});
services.AddNamedPool<DbConnection>("WritePool", configuration, options =>
{
options.MinSize = 2;
options.MaxSize = 10;
});Each named pool is keyed in the container. The key has the form "{name}.{typeof(TPoolItem).Name}.Pool" — for example, "ReadPool.DbConnection.Pool".
Build the key with ServiceKey.Create<TPoolItem>(name) rather than hand-formatting the string, then resolve through IPoolFactory<TPoolItem>:
public sealed class Repository(IPoolFactory<DbConnection> pools)
{
private readonly IPool<DbConnection> readPool =
pools.CreatePool(ServiceKey.Create<DbConnection>("ReadPool"));
private readonly IPool<DbConnection> writePool =
pools.CreatePool(ServiceKey.Create<DbConnection>("WritePool"));
}CreatePool caches the pool per key, so repeated calls with the same key return the same instance. Calling it with a key no pool was registered under throws.
A named pool reads an optional per-pool configuration section, "{key}_PoolOptions", layered over the shared "PoolOptions" section. The shared section binds first; the per-pool section overrides it property by property; the configureOptions action runs last. So shared defaults live in "PoolOptions", and only the differences live in each pool's section:
{
"PoolOptions": {
"LeaseTimeout": "00:00:30"
},
"ReadPool.DbConnection.Pool_PoolOptions": {
"MinSize": 5,
"MaxSize": 20
}
}To give a client type its own pool, register the two together. AddPool<TPoolItem, TClient> keys the pool by the client type and injects the IPool<TPoolItem> into the client's constructor:
services.AddPool<DbConnection, ReadClient>(configuration,
options =>
{
options.MinSize = 5;
options.MaxSize = 20;
},
client =>
{
// configure the resolved client
});Inject ReadClient directly and it holds its own dedicated pool. This is the cleanest option when each pool has exactly one consumer.
- Dependency injection — every registration extension and what it adds.
-
Metrics — each named pool reports under the same meter, distinguished by its
pool.nametag.