Class ValueObjectRegistry
Namespace: AdCodicem.ValueObjects.Metadata
Assembly: AdCodicem.ValueObjects.Abstractions.dll
Process-wide directory of the value object types known to the application.
public static class ValueObjectRegistry
Inheritance
Inherited Members
object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()
Remarks
The source generator emits a module initializer per assembly that registers every generated value object, so the common case is a lock-free dictionary hit with no reflection and no dynamic code — the registry is therefore usable under native AOT.
Methods
EnsureAssemblyRegistered(Assembly)
Runs the generated registration of an assembly, if it has one.
[RequiresUnreferencedCode("Locating the generated registration type of an assembly requires its metadata.")]
public static void EnsureAssemblyRegistered(Assembly assembly)
Parameters
assembly Assembly
Assembly declaring value objects.
Remarks
Module initializers are triggered by the first access to a member of the module, which model-building code that only reflects over types may never perform. Integrations call this before enumerating types.
GetRegistered()
Gets the descriptors registered so far.
public static IReadOnlyCollection<ValueObjectDescriptor> GetRegistered()
Returns
IReadOnlyCollection<ValueObjectDescriptor>
A snapshot of the registered descriptors.
Remarks
A generic value object appears through the constructions registered or resolved so far, never through its
definition, which
GetRegisteredGenericDefinitions()
Gets the definitions of the generic value objects registered so far.
public static IReadOnlyCollection<Type> GetRegisteredGenericDefinitions()
Returns
A snapshot of the generic type definitions.
Remarks
An integration configuring every value object up front, as the Entity Framework Core convention does, configures these by their definition and closes each construction where it meets one.
GetUnderlyingType(Type)
Gets the underlying value type of a value object.
public static Type? GetUnderlyingType(Type type)
Parameters
type Type
Value object type, possibly nullable.
Returns
Type?
The TValue of the
Remarks
Answering registers nothing. A registered type is answered from the registry, without reflection.
IsValueObject(Type)
Determines whether a type is a value object: a struct implementing
public static bool IsValueObject(Type type)
Parameters
type Type
Type to test, possibly nullable.
Returns
true when type, or the type it makes nullable, is a value object, which is
exactly when
Remarks
Answering registers nothing. A registered type is answered from the registry, without reflection.
Register(ValueObjectDescriptor)
Registers a descriptor, replacing any previous registration for the same type.
public static void Register(ValueObjectDescriptor descriptor)
Parameters
descriptor ValueObjectDescriptor
Descriptor to register.
Register<TSelf, TValue>(ValueObjectSchema)
Registers a value object without reflection.
public static void Register<TSelf, TValue>(ValueObjectSchema schema) where TSelf : struct, IValueObject<TSelf, TValue>
Parameters
schema ValueObjectSchema
Declarative constraints of the value object.
Type Parameters
TSelf
Value object type.
TValue
Underlying value type.
Register<TSelf, TValue>(ValueObjectSchema, JsonConverter<TSelf>)
Registers a value object and its System.Text.Json converter without reflection.
public static void Register<TSelf, TValue>(ValueObjectSchema schema, JsonConverter<TSelf> jsonConverter) where TSelf : struct, IValueObject<TSelf, TValue>
Parameters
schema ValueObjectSchema
Declarative constraints of the value object.
jsonConverter JsonConverter<TSelf>
The converter of the value object.
Type Parameters
TSelf
Value object type.
TValue
Underlying value type.
Remarks
A source-generated serializer context finds the converter through the descriptor, whatever the assembly declaring
the value object references. This is the registration native AOT asks of a construction of a generic value
object: Register<Code<Order>, string>(Code<Order>.Schema, new Code<Order>.ValueJsonConverter()).
Register<TSelf, TValue>(ValueObjectSchema, Func<JsonConverter<TSelf>>)
Registers a value object and the factory of its System.Text.Json converter without reflection.
public static void Register<TSelf, TValue>(ValueObjectSchema schema, Func<JsonConverter<TSelf>> jsonConverter) where TSelf : struct, IValueObject<TSelf, TValue>
Parameters
schema ValueObjectSchema
Declarative constraints of the value object.
jsonConverter Func<JsonConverter<TSelf>>
Creates the converter of the value object, the first time it is asked for.
Type Parameters
TSelf
Value object type.
TValue
Underlying value type.
Remarks
The generated registration calls this one. It runs for every value object when the declaring assembly loads, and an application that never serializes a value object through the descriptor never builds its converter.
RegisterGenericDefinition(Type)
Registers the definition of a generic value object, whose constructions the registry describes on demand.
public static void RegisterGenericDefinition(Type definition)
Parameters
definition Type
The generic type definition, typeof(Code<>), or that of a value object nested in a generic type,
typeof(Outer<>.Code).
Remarks
The generated registration calls this for a generic value object, since it knows none of the constructions the
application will use.
That takes reflection and dynamic code. Under native AOT, register each construction a type-driven integration
needs instead, which takes neither:
ValueObjectRegistry.Register<Code<Order>, string>(Code<Order>.Schema, new Code<Order>.ValueJsonConverter()).
The definition is checked without reading its interfaces, which native AOT does not keep for a generic type definition: this runs in the module initializer of every assembly declaring a generic value object, where a failure would stop the application before it starts.
Exceptions
definition is not the generic type definition of a struct carrying the
TryGet(Type, out ValueObjectDescriptor?)
Looks up an already registered descriptor.
public static bool TryGet(Type type, out ValueObjectDescriptor? descriptor)
Parameters
type Type
Value object type, possibly nullable.
descriptor ValueObjectDescriptor?
The descriptor when found.
Returns
true when a descriptor is registered for type.
TryResolve(Type, out ValueObjectDescriptor?)
Looks up a descriptor, building it by reflection when the type has not registered itself.
[RequiresDynamicCode("Building a descriptor for an unregistered value object instantiates a generic method at run time.")]
[RequiresUnreferencedCode("Building a descriptor for an unregistered value object inspects its interfaces and attributes.")]
public static bool TryResolve(Type type, out ValueObjectDescriptor? descriptor)
Parameters
type Type
Value object type, possibly nullable.
descriptor ValueObjectDescriptor?
The descriptor when the type is a value object.
Returns
true when type is a value object, as