Class GeneratedTypeDiscoveryRegistry
- Namespace
- Cratis.Types
- Assembly
- Cratis.Fundamentals.dll
Holds compile-time generated type discovery providers registered by consuming assemblies.
public static class GeneratedTypeDiscoveryRegistry
- Inheritance
-
GeneratedTypeDiscoveryRegistry
- Inherited Members
Properties
Providers
Gets the currently registered providers.
public static IEnumerable<ICanProvideAssembliesForDiscovery> Providers { get; }
Property Value
Methods
EnsureProvidersRegistered()
Ensures every generated provider reachable through the assembly reference closure has been registered.
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Referenced assemblies must be visited to run module initializers that register generated providers.")]
public static void EnsureProvidersRegistered()
Remarks
A generated provider registers itself from a [ModuleInitializer] in the assembly that
declares it, and a module constructor runs only when the runtime first needs that assembly -
which for a referenced assembly nothing has touched yet is never.
Load(AssemblyName) does not run one either. So this walks the reference
closure from the loaded assemblies and the entry assembly, loads what is missing, and runs each
module constructor explicitly. An assembly that cannot be loaded is skipped rather than thrown
on: the closure of a real application names assemblies that are genuinely absent at runtime. A
module initializer that itself throws is not swallowed - it propagates, and because the runtime
caches a failed type initialization, every later call throws the same way.
Safe to call repeatedly and from several threads at once. Module constructors run once per process and Register(ICanProvideAssembliesForDiscovery) deduplicates by provider type, so a repeated call cannot double-register; a call that finds no assembly the previous walk had not already processed returns without walking at all. An assembly loaded after - or concurrently with - a walk is not in that set, so the next call walks again and picks it up.
AddBindingsByConvention and AddSelfBindings call this for themselves. A host that
builds a type universe before either of those - resolving ITypes from a
container, or reading Instance - has to call this first, or the universe is
built from an incomplete provider set and silently misses everything the walk would have brought
in. It does not announce itself: a shorter discovery result is indistinguishable from a feature
nobody wrote.
Register(ICanProvideAssembliesForDiscovery)
Registers a generated provider.
public static void Register(ICanProvideAssembliesForDiscovery provider)
Parameters
providerICanProvideAssembliesForDiscoveryThe provider to register.