Scan [Event]-annotated types at compile time and emit a DI extension that pre-constructs all EventSchema instances — eliminating startup reflection and enabling schema auto-discovery without runtime assembly scanning.
The problem today: EventSchemaFactory.CreateFromType() walks every property of an event class via reflection at application startup (GetMembers(), GetCustomAttribute<>(), NullabilityInfoContext). The existing benchmarks confirm that reflection-based schema construction is meaningfully slower than its manual equivalent. Roadmap item 11 (AsyncAPI export tooling) also requires runtime assembly scanning to auto-discover [Event]-annotated types — an approach that is brittle in trimmed / AOT-compiled deployments and cannot run inside a dotnet CLI tool without instantiating the application host.
What we will build: An additional generator within Deveel.Events.Generators that:
- Scans every
[Event]-annotated type in the current compilation.
- Emits a
static partial class GeneratedEventSchemas containing a pre-constructed EventSchema instance per type, building the complete property tree — names, data types, required / range constraints — purely from annotation metadata resolved at compile time.
- Emits an
AddGeneratedEventSchemas(this IServiceCollection services) extension method that registers each pre-computed schema in the DI container as part of the IEventSchemaFactory resolution chain, replacing startup-time reflection with direct object construction.
- Provides the compile-time schema metadata consumed by the
dotnet global-tool export path planned in item 11, enabling AsyncAPI / YAML export without a running application host.
- Emits compile-time diagnostics:
DLEVT004 — [EventProperty]'s schemaOrVersion argument is neither a valid absolute URI nor a parseable version string (mirrors the ArgumentException thrown at runtime today).
DLEVT005 — two members of the same class carry conflicting [EventProperty] names.
Benefits:
- Schema construction is effectively O(1) at application startup — all reflection-equivalent work is performed at build time, regardless of the number or complexity of event types registered.
- Directly unblocks roadmap item 11: the compile-time metadata provides an assembly-scan surrogate that works in trimmed, AOT-compiled, and tool-invoked contexts without a live host.
- Invalid annotation configurations surface as build errors rather than startup exceptions, improving CI feedback loops.
- Works alongside the runtime
EventSchemaFactory — the generator supplements rather than replaces it for dynamically-loaded types that cannot be analysed at compile time.
The problem today:
EventSchemaFactory.CreateFromType()walks every property of an event class via reflection at application startup (GetMembers(),GetCustomAttribute<>(),NullabilityInfoContext). The existing benchmarks confirm that reflection-based schema construction is meaningfully slower than its manual equivalent. Roadmap item 11 (AsyncAPI export tooling) also requires runtime assembly scanning to auto-discover[Event]-annotated types — an approach that is brittle in trimmed / AOT-compiled deployments and cannot run inside adotnetCLI tool without instantiating the application host.What we will build: An additional generator within
Deveel.Events.Generatorsthat:[Event]-annotated type in the current compilation.static partial class GeneratedEventSchemascontaining a pre-constructedEventSchemainstance per type, building the complete property tree — names, data types, required / range constraints — purely from annotation metadata resolved at compile time.AddGeneratedEventSchemas(this IServiceCollection services)extension method that registers each pre-computed schema in the DI container as part of theIEventSchemaFactoryresolution chain, replacing startup-time reflection with direct object construction.dotnetglobal-tool export path planned in item 11, enabling AsyncAPI / YAML export without a running application host.DLEVT004—[EventProperty]'sschemaOrVersionargument is neither a valid absolute URI nor a parseable version string (mirrors theArgumentExceptionthrown at runtime today).DLEVT005— two members of the same class carry conflicting[EventProperty]names.Benefits:
EventSchemaFactory— the generator supplements rather than replaces it for dynamically-loaded types that cannot be analysed at compile time.