From 04aa5fe7b1d9baee14e721f55f2fd4f2a2a82fd3 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 28 Apr 2024 15:39:46 +0200 Subject: [PATCH] refactor: Cache ConstructorInfo (#1455) --- src/bunit/Rendering/BunitRenderer.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/bunit/Rendering/BunitRenderer.cs b/src/bunit/Rendering/BunitRenderer.cs index 0c371de92..d1c8998f8 100644 --- a/src/bunit/Rendering/BunitRenderer.cs +++ b/src/bunit/Rendering/BunitRenderer.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -13,6 +14,7 @@ public sealed class BunitRenderer : Renderer { private readonly BunitServiceProvider services; private readonly List disposalTasks = []; + private static readonly ConcurrentDictionary componentActivatorCache = new(); [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_isBatchInProgress")] private static extern ref bool GetIsBatchInProgressField(Renderer renderer); @@ -214,11 +216,28 @@ protected override ComponentState CreateComponentState(int componentId, ICompone var TComponent = component.GetType(); var renderedComponentType = typeof(RenderedComponent<>).MakeGenericType(TComponent); - var renderedComponent = Activator.CreateInstance(renderedComponentType, this, componentId, component, services, parentComponentState); + var renderedComponent = CreateComponentInstance(); Debug.Assert(renderedComponent is not null, "RenderedComponent should not be null"); return (ComponentState)renderedComponent; + + object CreateComponentInstance() + { + var constructorInfo = componentActivatorCache.GetOrAdd(renderedComponentType, type + => type.GetConstructor( + [ + typeof(BunitRenderer), + typeof(int), + typeof(IComponent), + typeof(IServiceProvider), + typeof(ComponentState) + ])!); + + Debug.Assert(constructorInfo is not null, "Could not find ConstructorInfo"); + + return constructorInfo.Invoke([this, componentId, component, services, parentComponentState]); + } } ///