Enhanced C#
Loyc library documentation
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
Nested classes | Public static fields | Properties | Public Member Functions | Static Public Member Functions | List of all members
TypeTagRegistry Class Reference

The module that registers and resolves type tags: it encapsulates (1) the bidirectional dictionary between type tags and .NET types, (2) the convention by which tags are attached to synchronizers (the TypeTagAttribute), and (3) the policy for tags in a data stream that don't match anything registered or expected. All three are customizable: the dictionary via Add, and the convention and policies by overriding the virtual methods in a derived class and swapping it in with SetDefault (the Ambient Service Pattern). More...


Source file:

Remarks

The module that registers and resolves type tags: it encapsulates (1) the bidirectional dictionary between type tags and .NET types, (2) the convention by which tags are attached to synchronizers (the TypeTagAttribute), and (3) the policy for tags in a data stream that don't match anything registered or expected. All three are customizable: the dictionary via Add, and the convention and policies by overriding the virtual methods in a derived class and swapping it in with SetDefault (the Ambient Service Pattern).

This registry deliberately knows nothing about synchronizers: which synchronizer handles which type is the concern of TypeSyncRegistry, which records tags it discovers here (in the instance that is Default at the time of the Add call).

Registry behavior can be changed by writing a derived class and installing it by changing the GlobalDefault or calling SetDefault. For example, you could change the error-handling policies:

Public static fields

static TypeTagRegistry Default => _ambient.Value
 The ambient tag registry: the current execution context's override (see SetDefault) if one is active, else GlobalDefault. See AmbientService{T} for how overrides flow across await and why the no-override case costs only a static field read. More...
 

Properties

static TypeTagRegistry GlobalDefault [get, set]
 The registry used by every execution context that has no ambient override from SetDefault. It can be replaced, e.g. to install a subclass with a different tagging convention app-wide. More...
 

Public Member Functions

void Add (Type type, string tag, bool replaceExisting=false)
 Associates a type tag with a type (in both directions). Re-adding an identical association is harmless; a conflicting one throws unless replaceExisting is true. More...
 
string TagOf (Type type)
 Gets the tag registered for a type, or null. More...
 
Type TypeOf (string tag)
 Gets the type registered for a tag, or null. More...
 
string AttributeTagOf (Delegate syncFunc)
 Gets the tag declared by a synchronizer function, or null. More...
 
virtual string AttributeTagOf (MethodInfo synchronizerMethod)
 Gets the tag declared by a synchronizer method: by default, a TypeTagAttribute on the method or, failing that, on its declaring type. Override to change the convention (e.g. to derive tags from type names). More...
 
virtual string AttributeTagOf (Type synchronizerType, Type valueType)
 Gets the tag declared by a synchronizer type (e.g. a struct implementing ISyncObject{SM, T}) as it applies to values of type valueType: by default, a TypeTagAttribute on a method whose return type is valueType (so one synchronizer type can serve multiple value types with different tags), then on the type itself. More...
 
virtual Type UnknownTagError (string tag, Type expectedType, FieldId field)
 Called when a dynamically-typed read encounters a tag that is not in the dictionary. The default throws FormatException. An override may return a substitute type to synchronize instead (it must have a registered synchronizer), or null to fall back to the statically-expected type. More...
 
virtual void TagMismatchError (string expectedTag, string tagInStream, Type expectedType, FieldId field)
 Called when a statically-typed read encounters a tag that differs from the tag of the synchronizer being used. The default throws FormatException; if an override returns normally, the read proceeds with the expected synchronizer anyway. More...
 

Static Public Member Functions

static AmbientService
< TypeTagRegistry >.Saved 
SetDefault (TypeTagRegistry newValue)
 Sets the current async-local default registry. Designed to be used in a using statement, which restores the old value at the end. Caution: AsyncLocal variables are slow, causing a small performance hit when using this. More...
 

Member Function Documentation

void TypeTagRegistry.Add ( Type  type,
string  tag,
bool  replaceExisting = false 
)
inline

Associates a type tag with a type (in both directions). Re-adding an identical association is harmless; a conflicting one throws unless replaceExisting is true.

string TypeTagRegistry.AttributeTagOf ( Delegate  syncFunc)
inline

Gets the tag declared by a synchronizer function, or null.

This is called on a hot path: Impl.ObjectSyncher resolves the tag every time a delegate-based synchronizer is used for a field. It is cached by delegate value because obtaining Delegate.Method is a (surprisingly slow) reflection operation that must not run per call.

Referenced by TypeSyncRegistry.Add().

virtual string TypeTagRegistry.AttributeTagOf ( MethodInfo  synchronizerMethod)
inlinevirtual

Gets the tag declared by a synchronizer method: by default, a TypeTagAttribute on the method or, failing that, on its declaring type. Override to change the convention (e.g. to derive tags from type names).

virtual string TypeTagRegistry.AttributeTagOf ( Type  synchronizerType,
Type  valueType 
)
inlinevirtual

Gets the tag declared by a synchronizer type (e.g. a struct implementing ISyncObject{SM, T}) as it applies to values of type valueType: by default, a TypeTagAttribute on a method whose return type is valueType (so one synchronizer type can serve multiple value types with different tags), then on the type itself.

static AmbientService<TypeTagRegistry>.Saved TypeTagRegistry.SetDefault ( TypeTagRegistry  newValue)
static

Sets the current async-local default registry. Designed to be used in a using statement, which restores the old value at the end. Caution: AsyncLocal variables are slow, causing a small performance hit when using this.

virtual void TypeTagRegistry.TagMismatchError ( string  expectedTag,
string  tagInStream,
Type  expectedType,
FieldId  field 
)
virtual

Called when a statically-typed read encounters a tag that differs from the tag of the synchronizer being used. The default throws FormatException; if an override returns normally, the read proceeds with the expected synchronizer anyway.

string TypeTagRegistry.TagOf ( Type  type)

Gets the tag registered for a type, or null.

Type TypeTagRegistry.TypeOf ( string  tag)

Gets the type registered for a tag, or null.

virtual Type TypeTagRegistry.UnknownTagError ( string  tag,
Type  expectedType,
FieldId  field 
)
virtual

Called when a dynamically-typed read encounters a tag that is not in the dictionary. The default throws FormatException. An override may return a substitute type to synchronize instead (it must have a registered synchronizer), or null to fall back to the statically-expected type.

Member Data Documentation

TypeTagRegistry TypeTagRegistry.Default => _ambient.Value
static

The ambient tag registry: the current execution context's override (see SetDefault) if one is active, else GlobalDefault. See AmbientService{T} for how overrides flow across await and why the no-override case costs only a static field read.

Referenced by TypeSyncRegistry.Add(), and TypeSyncRegistry.Add< T >().

Property Documentation

TypeTagRegistry TypeTagRegistry.GlobalDefault
staticgetset

The registry used by every execution context that has no ambient override from SetDefault. It can be replaced, e.g. to install a subclass with a different tagging convention app-wide.