[Blazor] Generate framework component metadata - #68300
Draft
javiercn wants to merge 5 commits into
Draft
Conversation
javiercn
force-pushed
the
javiercn-framework-component-metadata
branch
from
August 9, 2026 11:58
c68b966 to
d9a8361
Compare
javiercn
force-pushed
the
javiercn-framework-component-metadata
branch
from
August 9, 2026 12:46
d9a8361 to
27ac444
Compare
This was referenced Aug 9, 2026
javiercn
force-pushed
the
javiercn-framework-component-metadata
branch
from
August 9, 2026 19:34
27ac444 to
617eaa6
Compare
Discover framework-owned component assemblies and merge their owner descriptors with application metadata. Add generic factory imports and generated UnsafeAccessors for Components, Web, Forms, and Endpoints. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Cover core provider imports, explicit closed generic roots, owner factory selection, and provider-aware generator diagnostics while retaining application descriptor isolation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add owner descriptors for Authorization, QuickGrid, Media, and WebAssembly Authentication, including constrained generic factories, private injection bridges, and required construction paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise the complete built-in component descriptor matrix, including constrained QuickGrid factories, private injectable bridges, Media construction, and remote authentication component families. Framework JS callback coverage remains in its lower stack layer. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reference optional framework packages beside their owner providers and root representative closed generic components for Forms, virtualization, QuickGrid, and remote authentication in the existing JIT feature harness. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
javiercn
force-pushed
the
javiercn-framework-component-metadata
branch
from
August 9, 2026 21:54
617eaa6 to
58a0cfe
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This is layer 5 of 6 for the Aspire Dashboard Native AOT feature, stacked on #68299. Across five commits and 23 files, it teaches the Razor components metadata generator to import component descriptions from the framework assemblies that own those components, then adds providers for Components, Web, Forms, Endpoints, Authorization, QuickGrid, Media, and WebAssembly Authentication. The governing constraint is that application metadata and framework-owner metadata must compose without reflection, while optional assemblies contribute nothing unless the application actually references them; strict reflection switches and Native AOT execution remain in layer 6.
Design
There is no new public API. The generator emits an internal, compile-time-only attribute that lets the feature application name closed generic roots which cannot be inferred from an open generic definition:
Each owner assembly implements the same internal convention: a type named
Microsoft.AspNetCore.Components.Infrastructure.BuiltInComponentDescriptorsexposesGetDescriptors()for fixed components and named generic factory methods for closed families. The application generator deliberately does not duplicate framework internals: owner providers can access private members, required constructors, and internal helper component graphs safely, while the generator carries only the data required to bind to those factories.This owner-provider design was chosen over application-side reflection or re-describing framework private state. It also preserves package isolation: the known provider list is filtered against the host compilation's referenced assemblies, so Authorization, QuickGrid, Media, and WebAssembly Authentication metadata is imported only when those packages are present. Framework JS callback providers are unchanged and remain owned by the earlier JSInterop layer.
Implementation
The generator starts from the metadata context a consumer already registers. It computes application descriptors once, discovers referenced owner providers, collects implicit and explicitly rooted generic factories, and merges those inputs into the context model:
Emission preserves the lower layer's application descriptors and spreads owner descriptors after them. Both fixed providers and generic factories are linked with generated
UnsafeAccessordeclarations, so the runtime receives ordinary descriptor arrays with no assembly scanning,MakeGenericType, or reflective member access:A fixed owner inventory is represented by Components'
Router: the provider owns activation, every parameter, and injections whose setters are private. Web, Forms, and Endpoints use the same pattern for their non-generic inventories.The remaining provider behaviors form four equivalence classes; one representative and each delta are shown here:
ValidationMessage<T>,Virtualize<T>,OwningComponentBase, QuickGrid families, andRemoteAuthenticatorViewCore<TState>preserve concrete arguments, constraints, and trimming annotations. QuickGrid additionally contributes the internal cascading context and tuple-shaped virtualization helper needed byQuickGrid<T>:AuthorizeView,AuthorizeRouteView,CascadingAuthenticationState, and the private nestedAuthorizeRouteViewCore; owner-side helpers construct the private core whileUnsafeAccessorbridges its inherited private parameters and services. QuickGrid and WebAssembly Authentication use the same bridge pattern for private injections.Image,Video, andFileDownloadcannot use a plain parameterless factory becauseSourceis required. Their owner provider deliberately constructsnew Image { Source = null! }(and peers) before normal parameter assignment and supplies the private JS runtime/logger injections.RemoteAuthenticatorViewCore<TAuthenticationState>preserveswhere TAuthenticationState : RemoteAuthenticationStateplus theJsonSerializedDAM requirement, and closes all five service types over the same authentication-state type.The feature application roots representative closed instances beside their optional assembly references, covering generic Forms inputs, virtualization, application generics, QuickGrid's grid/column/notifier graph, and remote authentication:
Outcome
Validation: the complete built-in descriptor generator matrix passed 113/113 tests. Fast affected suites across Components, Web, Forms, Endpoints, Authorization, QuickGrid, Media, and WebAssembly Authentication passed 2,784 tests with 8 existing skips. Native AOT execution and strict reflection-disabled validation are intentionally deferred to layer 6.