diff --git a/src/ScissorHands.Web/Renderers/ComponentRenderer.cs b/src/ScissorHands.Web/Renderers/ComponentRenderer.cs index 9485785..d129188 100644 --- a/src/ScissorHands.Web/Renderers/ComponentRenderer.cs +++ b/src/ScissorHands.Web/Renderers/ComponentRenderer.cs @@ -1,8 +1,12 @@ +using System.Reflection; + using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using ScissorHands.Theme; + namespace ScissorHands.Web.Renderers; /// @@ -15,6 +19,39 @@ public sealed class ComponentRenderer(IServiceScopeFactory scopeFactory, ILogger private readonly IServiceScopeFactory _scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory)); private readonly ILoggerFactory _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + // Lazy initialization of cascading parameter names discovered via reflection + private static readonly Lazy> _cascadingParameterNames = new(() => + { + var parameterNames = new HashSet(StringComparer.Ordinal); + + // Discover all types in the ScissorHands.Theme assembly that have cascading parameters + var themeAssembly = typeof(PageViewBase).Assembly; + + try + { + var allTypes = themeAssembly.GetExportedTypes(); + + foreach (var type in allTypes) + { + // Find all properties with CascadingParameter attribute + var cascadingProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Where(p => p.GetCustomAttribute() is not null); + + foreach (var property in cascadingProperties) + { + parameterNames.Add(property.Name); + } + } + } + catch (ReflectionTypeLoadException) + { + // If type loading fails, fall back to empty set + // This should not happen in normal operation, but provides safety + } + + return parameterNames; + }); + /// public async Task RenderAsync(Type layoutType, IDictionary parameters, CancellationToken cancellationToken = default) where TComponent : IComponent @@ -32,18 +69,9 @@ public async Task RenderAsync(Type layoutType, IDictionary(0); var seq = 1; - var cascadingKeys = new HashSet(StringComparer.Ordinal) - { - "Documents", - "Document", - "Plugins", - "Theme", - "Site" - }; - foreach (var kvp in parameters) { - if (cascadingKeys.Contains(kvp.Key)) + if (_cascadingParameterNames.Value.Contains(kvp.Key)) { continue; }