Skip to content

Factory Registry ​

Namespace: DesignPatterns.Creational

Overview ​

Map keys to product factories — similar to Strategy but for creating instances (Create() / IFactoryRegistry).

Runtime ​

  • IFactoryRegistry<TKey, TProduct> — extends read-only registry with Create
  • IAsyncFactoryRegistry<TKey, TProduct> — async variant with CreateAsync
  • IPooledFactoryRegistry<TKey, TProduct> — pooled variant with RentAsync / Return (backed by ArrayPool<T>)
  • FactoryRegistryBuilder<TKey, TProduct> — fluent manual registration
  • AsyncFactoryRegistryBuilder<TKey, TProduct> — fluent manual async/pooled registration

Source generator ​

[RegisterFactory(typeof(TProduct), "key")] on factory types; partial static registry holder. Optional IsAsync = true for async factories and PoolSize = N for pooled factories.

csharp
[RegisterFactory(typeof(IProduct), "standard")]
public sealed class StandardProductFactory : IProductFactory { ... }

[RegisterFactory(typeof(IProduct), "premium", IsAsync = true)]
public sealed class PremiumProductFactory : IAsyncFactory<IProduct> { ... }

[RegisterFactory(typeof(IProduct), "buffer", PoolSize = 16)]
public sealed class BufferProductFactory : IAsyncFactory<IProduct> { ... }

When IsAsync = true or the factory implements IAsyncFactory<TProduct>, the generator emits an IAsyncFactoryRegistry in addition to the sync registry. When PoolSize > 0, the generator emits an IPooledFactoryRegistry.

Async factory registry ​

For asynchronous product creation, use IAsyncFactoryRegistry<TKey, TProduct>:

csharp
var registry = new AsyncFactoryRegistryBuilder<string, IProduct>()
    .Register("premium", ct => CreatePremiumAsync(ct))
    .Build();

var product = await registry.CreateAsync("premium");

Pooled factory registry ​

For reusable product instances with per-key object pooling, use IPooledFactoryRegistry<TKey, TProduct>:

csharp
var registry = new AsyncFactoryRegistryBuilder<string, IProduct>()
    .Register("buffer", () => new BufferProduct())
    .WithPooling(poolSize: 16)
    .Build();

var buffer = await registry.RentAsync("buffer");
// ... use buffer
registry.Return("buffer", buffer);

If a product implements IResettable, Reset() is called before returning it to the pool.

Diagnostics ​

DP020–DP023, DP025 (unknown literal keys). DP053–DP055 for async signature and pool size validation. See Registry key conventions.

Samples ​

SampleFocus
FactoryGenerated registry
RegisterFactoryManual builder

Maintainer doc: docs/FactoryRegistry.md (中文).

Released under the MIT License.