diff --git a/src/Components/Endpoints/src/Builder/ComponentTypeMetadata.cs b/src/Components/Endpoints/src/Builder/ComponentTypeMetadata.cs index 82c7d8099b8a..6278ee763e6c 100644 --- a/src/Components/Endpoints/src/Builder/ComponentTypeMetadata.cs +++ b/src/Components/Endpoints/src/Builder/ComponentTypeMetadata.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; +using static Microsoft.AspNetCore.Internal.LinkerFlags; + namespace Microsoft.AspNetCore.Components.Endpoints; /// @@ -12,7 +15,7 @@ public class ComponentTypeMetadata /// Initializes a new instance of . /// /// The component type. - public ComponentTypeMetadata(Type componentType) + public ComponentTypeMetadata([DynamicallyAccessedMembers(Component)] Type componentType) { Type = componentType; } @@ -20,5 +23,6 @@ public ComponentTypeMetadata(Type componentType) /// /// Gets the component type. /// + [DynamicallyAccessedMembers(Component)] public Type Type { get; } } diff --git a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs index b4b312882787..3013f3a0242e 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs @@ -2,16 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components.Discovery; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Primitives; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; -internal class RazorComponentEndpointDataSource : EndpointDataSource +internal class RazorComponentEndpointDataSource<[DynamicallyAccessedMembers(Component)] TRootComponent> : EndpointDataSource { private readonly object _lock = new(); private readonly List> _conventions = new(); diff --git a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSourceFactory.cs b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSourceFactory.cs index 62f3c76003ce..dc62124b3434 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSourceFactory.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSourceFactory.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components.Discovery; using Microsoft.AspNetCore.Components.Endpoints; using Microsoft.AspNetCore.Routing; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Infrastructure; @@ -20,7 +22,7 @@ public RazorComponentEndpointDataSourceFactory( _providers = providers; } - public RazorComponentEndpointDataSource CreateDataSource(IEndpointRouteBuilder endpoints) + public RazorComponentEndpointDataSource CreateDataSource<[DynamicallyAccessedMembers(Component)] TRootComponent>(IEndpointRouteBuilder endpoints) { var builder = ComponentApplicationBuilder.GetBuilder() ?? DefaultRazorComponentApplication.Instance.GetBuilder(); diff --git a/src/Components/Endpoints/src/Builder/RazorComponentEndpointFactory.cs b/src/Components/Endpoints/src/Builder/RazorComponentEndpointFactory.cs index e4530a4e2f46..c14ae30a8f2b 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentEndpointFactory.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentEndpointFactory.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components.Discovery; @@ -8,6 +9,7 @@ using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.Extensions.DependencyInjection; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -19,7 +21,7 @@ internal class RazorComponentEndpointFactory internal void AddEndpoints( #pragma warning restore CA1822 // It's a singleton List endpoints, - Type rootComponent, + [DynamicallyAccessedMembers(Component)] Type rootComponent, PageComponentInfo pageDefinition, IReadOnlyList> conventions, IReadOnlyList> finallyConventions) diff --git a/src/Components/Endpoints/src/Builder/RazorComponentsEndpointRouteBuilderExtensions.cs b/src/Components/Endpoints/src/Builder/RazorComponentsEndpointRouteBuilderExtensions.cs index 5861d7af977b..b91a4171b44c 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentsEndpointRouteBuilderExtensions.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentsEndpointRouteBuilderExtensions.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.AspNetCore.Components.Endpoints; using Microsoft.AspNetCore.Components.Infrastructure; @@ -9,20 +10,21 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Builder; /// -/// +/// /// public static class RazorComponentsEndpointRouteBuilderExtensions { /// - /// + /// /// /// /// - public static RazorComponentEndpointConventionBuilder MapRazorComponents(this IEndpointRouteBuilder endpoints) + public static RazorComponentEndpointConventionBuilder MapRazorComponents<[DynamicallyAccessedMembers(Component)] TRootComponent>(this IEndpointRouteBuilder endpoints) { ArgumentNullException.ThrowIfNull(endpoints); @@ -63,7 +65,7 @@ private static void AddBlazorWebJsEndpoint(IEndpointRouteBuilder endpoints) #endif } - private static RazorComponentEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder endpoints) + private static RazorComponentEndpointDataSource GetOrCreateDataSource<[DynamicallyAccessedMembers(Component)] TRootComponent>(IEndpointRouteBuilder endpoints) { var dataSource = endpoints.DataSources.OfType>().FirstOrDefault(); if (dataSource == null) diff --git a/src/Components/Endpoints/src/Builder/RenderModeEndpointProvider.cs b/src/Components/Endpoints/src/Builder/RenderModeEndpointProvider.cs index 4e2581d3b57b..d454971acd0e 100644 --- a/src/Components/Endpoints/src/Builder/RenderModeEndpointProvider.cs +++ b/src/Components/Endpoints/src/Builder/RenderModeEndpointProvider.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -31,7 +33,7 @@ public abstract IEnumerable GetEndpointBuilders( internal static void AddEndpoints( List endpoints, - Type rootComponent, + [DynamicallyAccessedMembers(Component)] Type rootComponent, IEnumerable renderModeEndpoints, IComponentRenderMode renderMode, List> conventions, diff --git a/src/Components/Endpoints/src/Builder/RootComponentMetadata.cs b/src/Components/Endpoints/src/Builder/RootComponentMetadata.cs index d86f8f750b16..f944db54dcdd 100644 --- a/src/Components/Endpoints/src/Builder/RootComponentMetadata.cs +++ b/src/Components/Endpoints/src/Builder/RootComponentMetadata.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; +using static Microsoft.AspNetCore.Internal.LinkerFlags; + namespace Microsoft.AspNetCore.Components.Endpoints; /// @@ -12,7 +15,7 @@ public class RootComponentMetadata /// Initializes a new instance of . /// /// The component type. - public RootComponentMetadata(Type rootComponentType) + public RootComponentMetadata([DynamicallyAccessedMembers(Component)] Type rootComponentType) { Type = rootComponentType; } @@ -20,5 +23,6 @@ public RootComponentMetadata(Type rootComponentType) /// /// Gets the component type. /// + [DynamicallyAccessedMembers(Component)] public Type Type { get; } } diff --git a/src/Components/Endpoints/src/DependencyInjection/IComponentPrerenderer.cs b/src/Components/Endpoints/src/DependencyInjection/IComponentPrerenderer.cs index 40adf5a4a18a..9e9f5b19ca06 100644 --- a/src/Components/Endpoints/src/DependencyInjection/IComponentPrerenderer.cs +++ b/src/Components/Endpoints/src/DependencyInjection/IComponentPrerenderer.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -21,7 +23,7 @@ public interface IComponentPrerenderer /// A task that completes with the prerendered content. ValueTask PrerenderComponentAsync( HttpContext httpContext, - Type componentType, + [DynamicallyAccessedMembers(Component)] Type componentType, IComponentRenderMode renderMode, ParameterView parameters); diff --git a/src/Components/Endpoints/src/Discovery/PageComponentBuilder.cs b/src/Components/Endpoints/src/Discovery/PageComponentBuilder.cs index c472bfee1d45..76e866360097 100644 --- a/src/Components/Endpoints/src/Discovery/PageComponentBuilder.cs +++ b/src/Components/Endpoints/src/Discovery/PageComponentBuilder.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Discovery; @@ -35,6 +37,7 @@ public required IReadOnlyList RouteTemplates /// /// Gets or sets the page type. /// + [DynamicallyAccessedMembers(Component)] public required Type PageType { get; set; } /// diff --git a/src/Components/Endpoints/src/Discovery/PageComponentInfo.cs b/src/Components/Endpoints/src/Discovery/PageComponentInfo.cs index 077f6eb117be..4cac0903ebee 100644 --- a/src/Components/Endpoints/src/Discovery/PageComponentInfo.cs +++ b/src/Components/Endpoints/src/Discovery/PageComponentInfo.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Discovery; @@ -20,7 +22,7 @@ internal class PageComponentInfo /// The page metadata. internal PageComponentInfo( string displayName, - Type type, + [DynamicallyAccessedMembers(Component)] Type type, string route, IReadOnlyList metadata) { @@ -38,6 +40,7 @@ internal PageComponentInfo( /// /// Gets the page type. /// + [DynamicallyAccessedMembers(Component)] public Type Type { get; } /// diff --git a/src/Components/Endpoints/src/Microsoft.AspNetCore.Components.Endpoints.csproj b/src/Components/Endpoints/src/Microsoft.AspNetCore.Components.Endpoints.csproj index 4ad66b63ab6c..44101368b937 100644 --- a/src/Components/Endpoints/src/Microsoft.AspNetCore.Components.Endpoints.csproj +++ b/src/Components/Endpoints/src/Microsoft.AspNetCore.Components.Endpoints.csproj @@ -35,6 +35,7 @@ + diff --git a/src/Components/Endpoints/src/RazorComponentEndpointHost.cs b/src/Components/Endpoints/src/RazorComponentEndpointHost.cs index 5ce1a4c4f0d3..b569e9880aa1 100644 --- a/src/Components/Endpoints/src/RazorComponentEndpointHost.cs +++ b/src/Components/Endpoints/src/RazorComponentEndpointHost.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using Microsoft.AspNetCore.Components.Rendering; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -19,8 +21,12 @@ internal class RazorComponentEndpointHost : IComponent { private RenderHandle _renderHandle; - [Parameter] public Type ComponentType { get; set; } = default!; - [Parameter] public IReadOnlyDictionary? ComponentParameters { get; set; } + [Parameter] + [DynamicallyAccessedMembers(Component)] + public Type ComponentType { get; set; } = default!; + + [Parameter] + public IReadOnlyDictionary? ComponentParameters { get; set; } public void Attach(RenderHandle renderHandle) => _renderHandle = renderHandle; diff --git a/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Prerendering.cs b/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Prerendering.cs index 7018501ca171..979cfaa17e16 100644 --- a/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Prerendering.cs +++ b/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Prerendering.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Components.Web.HtmlRendering; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -12,7 +14,7 @@ internal partial class EndpointHtmlRenderer { private static readonly object ComponentSequenceKey = new object(); - protected override IComponent ResolveComponentForRenderMode(Type componentType, int? parentComponentId, IComponentActivator componentActivator, IComponentRenderMode renderMode) + protected override IComponent ResolveComponentForRenderMode([DynamicallyAccessedMembers(Component)] Type componentType, int? parentComponentId, IComponentActivator componentActivator, IComponentRenderMode renderMode) { var closestRenderModeBoundary = parentComponentId.HasValue ? GetClosestRenderModeBoundary(parentComponentId.Value) @@ -50,14 +52,14 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, public ValueTask PrerenderComponentAsync( HttpContext httpContext, - Type componentType, + [DynamicallyAccessedMembers(Component)] Type componentType, IComponentRenderMode prerenderMode, ParameterView parameters) => PrerenderComponentAsync(httpContext, componentType, prerenderMode, parameters, waitForQuiescence: true); public async ValueTask PrerenderComponentAsync( HttpContext httpContext, - Type componentType, + [DynamicallyAccessedMembers(Component)] Type componentType, IComponentRenderMode? prerenderMode, ParameterView parameters, bool waitForQuiescence) @@ -98,7 +100,7 @@ public async ValueTask PrerenderComponentAsync( internal async ValueTask RenderEndpointComponent( HttpContext httpContext, - Type rootComponentType, + [DynamicallyAccessedMembers(Component)] Type rootComponentType, ParameterView parameters, bool waitForQuiescence) { diff --git a/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs b/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs index d6fb7881d0a3..1118dfeb5825 100644 --- a/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs +++ b/src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.cs @@ -18,6 +18,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Primitives; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -65,7 +66,7 @@ private void SetHttpContext(HttpContext httpContext) internal static async Task InitializeStandardComponentServicesAsync( HttpContext httpContext, - Type? componentType = null, + [DynamicallyAccessedMembers(Component)] Type? componentType = null, string? handler = null, IFormCollection? form = null) { diff --git a/src/Components/Endpoints/src/Rendering/SSRRenderModeBoundary.cs b/src/Components/Endpoints/src/Rendering/SSRRenderModeBoundary.cs index 08ae8135a557..8f1529e3e0a0 100644 --- a/src/Components/Endpoints/src/Rendering/SSRRenderModeBoundary.cs +++ b/src/Components/Endpoints/src/Rendering/SSRRenderModeBoundary.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Security.Cryptography; using System.Text; @@ -10,6 +11,7 @@ using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -21,6 +23,7 @@ internal class SSRRenderModeBoundary : IComponent { private static readonly ConcurrentDictionary _componentTypeNameHashCache = new(); + [DynamicallyAccessedMembers(Component)] private readonly Type _componentType; private readonly IComponentRenderMode _renderMode; private readonly bool _prerender; @@ -28,7 +31,7 @@ internal class SSRRenderModeBoundary : IComponent private IReadOnlyDictionary? _latestParameters; private string? _markerKey; - public SSRRenderModeBoundary(Type componentType, IComponentRenderMode renderMode) + public SSRRenderModeBoundary([DynamicallyAccessedMembers(Component)] Type componentType, IComponentRenderMode renderMode) { _componentType = componentType; _renderMode = renderMode; diff --git a/src/Components/Endpoints/src/Results/RazorComponentResult.cs b/src/Components/Endpoints/src/Results/RazorComponentResult.cs index 5ef2725601db..3049313f9a21 100644 --- a/src/Components/Endpoints/src/Results/RazorComponentResult.cs +++ b/src/Components/Endpoints/src/Results/RazorComponentResult.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -19,7 +21,7 @@ public class RazorComponentResult : IResult /// Constructs an instance of . /// /// The type of the component to render. This must implement . - public RazorComponentResult(Type componentType) + public RazorComponentResult([DynamicallyAccessedMembers(Component)] Type componentType) : this(componentType, null) { } @@ -29,7 +31,7 @@ public RazorComponentResult(Type componentType) /// /// The type of the component to render. This must implement . /// Parameters for the component. - public RazorComponentResult(Type componentType, object? parameters) + public RazorComponentResult([DynamicallyAccessedMembers(Component)] Type componentType, object? parameters) : this(componentType, CoerceParametersObjectToDictionary(parameters)) { } @@ -39,7 +41,7 @@ public RazorComponentResult(Type componentType, object? parameters) /// /// The type of the component to render. This must implement . /// Parameters for the component. - public RazorComponentResult(Type componentType, IReadOnlyDictionary? parameters) + public RazorComponentResult([DynamicallyAccessedMembers(Component)] Type componentType, IReadOnlyDictionary? parameters) { // Note that the Blazor renderer will validate that componentType implements IComponent and throws a suitable // exception if not, so we don't need to duplicate that logic here. @@ -57,6 +59,7 @@ public RazorComponentResult(Type componentType, IReadOnlyDictionary /// Gets the component type. /// + [DynamicallyAccessedMembers(Component)] public Type ComponentType { get; } /// diff --git a/src/Components/Endpoints/src/Results/RazorComponentResultExecutor.cs b/src/Components/Endpoints/src/Results/RazorComponentResultExecutor.cs index 764ecdbe8d5f..af14fa146f70 100644 --- a/src/Components/Endpoints/src/Results/RazorComponentResultExecutor.cs +++ b/src/Components/Endpoints/src/Results/RazorComponentResultExecutor.cs @@ -1,12 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Buffers; using System.Text; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.DependencyInjection; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; @@ -34,7 +36,7 @@ public virtual Task ExecuteAsync(HttpContext httpContext, RazorComponentResult r { response.StatusCode = result.StatusCode.Value; } - + return RenderComponentToResponse( httpContext, result.ComponentType, @@ -44,7 +46,7 @@ public virtual Task ExecuteAsync(HttpContext httpContext, RazorComponentResult r internal static Task RenderComponentToResponse( HttpContext httpContext, - Type componentType, + [DynamicallyAccessedMembers(Component)] Type componentType, IReadOnlyDictionary? componentParameters, bool preventStreamingRendering) { diff --git a/src/Components/Endpoints/src/Results/RazorComponentResultOfT.cs b/src/Components/Endpoints/src/Results/RazorComponentResultOfT.cs index 2933426ad91d..3019550b9100 100644 --- a/src/Components/Endpoints/src/Results/RazorComponentResultOfT.cs +++ b/src/Components/Endpoints/src/Results/RazorComponentResultOfT.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Http; +using static Microsoft.AspNetCore.Internal.LinkerFlags; namespace Microsoft.AspNetCore.Components.Endpoints; /// /// An that renders a Razor Component. /// -public class RazorComponentResult : RazorComponentResult where TComponent: IComponent +public class RazorComponentResult<[DynamicallyAccessedMembers(Component)] TComponent> : RazorComponentResult where TComponent: IComponent { /// /// Constructs an instance of .