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.
Remarks
This is the registration native AOT asks of a value object written by hand that a type-driven integration needs,
Register<Link, Uri>(Link.Schema), since AdCodicem.ValueObjects.Json gives
it a general-purpose one, closed through
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. A construction of a generic value object registered by hand under native AOT takes
the shorter
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.
Register<TSelf, TValue>(Func<JsonConverter<TSelf>>)
Registers a value object with the schema it declares and the factory of its System.Text.Json converter, without reflection.
public static void Register<TSelf, TValue>(Func<JsonConverter<TSelf>> jsonConverter) where TSelf : struct, IValueObject<TSelf, TValue>
Parameters
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 schema is Register<Code<Order>, string>(static () => new Code<Order>.ValueJsonConverter()).
Its descriptor is built in code, where the AOT compiler sees both type arguments, so a visitor
(
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>(static () => new Code<Order>.ValueJsonConverter()).
This runs in the module initializer of every assembly declaring a generic value object, where a failure would
stop the application before it starts. Its checks hold under native AOT, the
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.
Remarks
Asked for Iban?, it returns the descriptor of Iban: a descriptor describes the value object
itself, never its nullable type. A converter or a provider built from it closes its generic types over
type, which a
constraint on the value object refuses for a
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 generated members.")]
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
Remarks
Asked for Iban?, it returns the descriptor of Iban, as
A type nothing registered is described with the