Skip to main content
Version: Preview (0.3.0-preview.205)

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​

object ← ValueObjectRegistry

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.

additionally falls back to reflection for hand-written value objects, for modules whose initializer has not run yet, and for the constructions of a generic value object, whose generic definition is all the initializer can register. It is annotated as requiring dynamic code, and its result is cached, so a given type pays that cost at most once.

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 lists.

GetRegisteredGenericDefinitions()​

Gets the definitions of the generic value objects registered so far.

public static IReadOnlyCollection<Type> GetRegisteredGenericDefinitions()

Returns​

IReadOnlyCollection<Type>

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 the type implements over itself, or null when the type is not a value object as defines one — a class or a struct implementing only included.

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 over itself, the one shape a descriptor, a converter or a model binder can be built for.

public static bool IsValueObject(Type type)

Parameters​

type Type

Type to test, possibly nullable.

Returns​

bool

true when type, or the type it makes nullable, is a value object, which is exactly when describes it. An interface, a class, or a struct carrying only the marker or is not one.

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. then describes each construction it is asked for from the members the generator wrote on it, its schema and its converter, and caches the descriptor.

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​

ArgumentException

definition is not the generic type definition of a struct carrying the marker.

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​

bool

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​

bool

true when type is a value object, as defines one.