Table of Contents

Class FeatureCatalogueManager

Namespace
EncDotNet.S100.Features
Assembly
EncDotNet.S100.Features.dll

Caches parsed FeatureCatalogue and FeatureCatalogueDecoder instances by product specification reference, so that the (relatively expensive) XML parse happens at most once per spec per manager lifetime.

public sealed class FeatureCatalogueManager : IDisposable, ICatalogueProvider<FeatureCatalogue>
Inheritance
FeatureCatalogueManager
Implements
Inherited Members

Remarks

Mirrors the PortrayalCatalogueManager pattern used for portrayal catalogues. The manager wraps a caller-supplied resolver and lazily parses the feature catalogue on first access for each spec. Subsequent calls to GetCatalogue(SpecRef) or GetDecoder(SpecRef) for the same spec return the cached instance.

Each cache slot is keyed by SpecRef, so requests for distinct editions of the same product (e.g. S-101/1.2.0 versus S-101/2.0.0) parse and cache independently. The string-based overloads remain for back-compat: they delegate via TryNormalize(string?, out string) and a default SpecVersion, so all string callers share a single cache slot per product name.

Constructors

FeatureCatalogueManager(Func<SpecRef, Stream?>)

Initializes a new FeatureCatalogueManager with a SpecRef-aware stream resolver. Use this overload when the resolver needs to differentiate between editions of the same product.

public FeatureCatalogueManager(Func<SpecRef, Stream?> resolver)

Parameters

resolver Func<SpecRef, Stream>

A function that, given a SpecRef, returns a readable Stream containing the Feature Catalogue XML, or null if no catalogue is available for that spec.

FeatureCatalogueManager(Func<string, Stream?>?)

Initializes a new FeatureCatalogueManager with a string-based stream resolver. The resolver receives the product specification name (e.g. "S-101"). The edition portion of SpecRef is ignored.

public FeatureCatalogueManager(Func<string, Stream?>? resolver = null)

Parameters

resolver Func<string, Stream>

A function that, given a product specification name, returns a readable Stream containing the Feature Catalogue XML, or null if no catalogue is available for that spec. When null, the manager always returns null from GetCatalogue(SpecRef).

Methods

Dispose()

Disposes every IAssetSource registered through SetSource(SpecRef, IAssetSource). Cached catalogues themselves are plain in-memory objects and do not require disposal.

public void Dispose()

GetCatalogue(SpecRef)

Returns the cached FeatureCatalogue for the given spec reference, parsing it from the resolver on first access. Each SpecRef (combination of name + edition) is cached independently. Returns null when the resolver does not provide a stream or parsing fails.

public FeatureCatalogue? GetCatalogue(SpecRef spec)

Parameters

spec SpecRef

Returns

FeatureCatalogue

GetCatalogue(string)

Returns the cached FeatureCatalogue for the given spec name, parsing it from the resolver on first access. Returns null when the resolver does not provide a stream for the spec or parsing fails.

public FeatureCatalogue? GetCatalogue(string productSpec)

Parameters

productSpec string

The product specification identifier (e.g. "S-101").

Returns

FeatureCatalogue

GetCatalogueHashAsync(SpecRef, CancellationToken)

Returns a stable lowercase hex SHA-256 hash of the raw Feature Catalogue XML bytes for spec, or null when no catalogue is available. The hash reflects the actual resolved content — including any CLI / settings override the resolver applies — so it is a safe cache-invalidation input where a declared catalogue version string would miss an override that changes the file without bumping its version.

public ValueTask<string?> GetCatalogueHashAsync(SpecRef spec, CancellationToken cancellationToken = default)

Parameters

spec SpecRef
cancellationToken CancellationToken

Returns

ValueTask<string>

Remarks

Implements GetCatalogueHashAsync(SpecRef, CancellationToken). The hash is computed at most once per spec and memoized; a transient failure (returning null) is not memoized, so a later call retries. The memoized computation is decoupled from cancellationToken so one caller's cancellation cannot poison the shared result.

GetDecoder(SpecRef)

Returns a cached FeatureCatalogueDecoder for the given spec reference, building it from the cached catalogue on first access. Returns null when no catalogue is available.

public FeatureCatalogueDecoder? GetDecoder(SpecRef spec)

Parameters

spec SpecRef

Returns

FeatureCatalogueDecoder

GetDecoder(string)

Returns a cached FeatureCatalogueDecoder for the given spec name. See GetDecoder(SpecRef) for behaviour.

public FeatureCatalogueDecoder? GetDecoder(string productSpec)

Parameters

productSpec string

Returns

FeatureCatalogueDecoder

SetSource(SpecRef, IAssetSource)

Registers an IAssetSource for the given spec reference. See SetSource(string, IAssetSource) for the precedence rules and disposal semantics.

public void SetSource(SpecRef spec, IAssetSource source)

Parameters

spec SpecRef
source IAssetSource

SetSource(string, IAssetSource)

Registers an IAssetSource as the bundled fallback for the given product specification. The resolver delegate supplied to the manager constructor still takes precedence; the source is only consulted when the resolver returns null for that spec.

public void SetSource(string productSpec, IAssetSource source)

Parameters

productSpec string
source IAssetSource

Remarks

The manager assumes ownership of source for disposal purposes — a subsequent SetSource(SpecRef, IAssetSource) for the same spec disposes the previous source, and Dispose() disposes every registered source. The source is expected to expose a FeatureCatalogue.xml asset matching the convention used by EncDotNet.S100.Specifications.Specification.