docs
Systems
Contracts
ParamsSystem
Architecture and Design

Overview

The ParamsSystem is a small contract layer made of three types:

  • ParamKey<T> is a typed, named key. Its generic argument declares the type of value it holds.
  • IParamKey is the untyped interface that every ParamKey<T> implements. It exposes only the key's name.
  • Params is the container. It maps keys to values.

The namespace for ParamKey<T> and IParamKey is SaffronLibrary.Prime.Systems.Param.Interfaces. The namespace for Params is SaffronLibrary.Prime.Systems.Param.

Design patterns used

  • Typed key with an untyped storage key. ParamKey<T> carries the value type at compile time. Params stores entries under IParamKey, because a generic key type cannot be used as a single dictionary key type. The untyped interface lets keys of different value types share one dictionary.
  • Generic accessors. Set<T>, Get<T>, and TryGet<T> take a ParamKey<T>, so the compiler ensures the value type matches the key type.
  • Static guard helpers. Require, RequireObject, and the RequireObject overload for ParamKey<object> are static methods that check presence and type, then throw InvalidOperationException with a message naming the key.

Key concepts

  • Key name. A unique string, exposed as KeyName. The name is the identity used when Params is flattened with ToDictionary.
  • Key identity in storage. ParamKey<T> does not override equality, so storage in Params compares keys by reference. Two separate key instances are different entries even if they share a name.
  • Set and replace. Set stores a value under a key. Setting the same key again replaces the earlier value.
  • Presence checks. Has reports whether a key has a value. TryGet returns a value when it exists and reports success through its return value.

Data flow

  1. A domain defines ParamKey<T> instances, usually as static readonly fields in a keys class.
  2. A caller creates an empty Params and fills it with Set.
  3. The populated Params is carried by the message that uses it.
  4. A receiver reads values with Get, TryGet, Has, or one of the Require helpers.

Error behavior

  • Get throws KeyNotFoundException when no value is stored under the key.
  • Require and RequireObject throw InvalidOperationException when the key is missing or the stored value is not of the expected type. The ParamKey<object> overload of RequireObject also throws ArgumentNullException for null arguments.
  • TryGet and Has do not throw for a missing key.