Skip to content

Commit b83721c

Browse files
authored
[Blazor] Clear caches on HotReload (#62880)
1 parent 6187def commit b83721c

14 files changed

+120
-2
lines changed

src/Components/Authorization/src/AttributeAuthorizeDataCache.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,24 @@
33

44
using System.Collections.Concurrent;
55
using Microsoft.AspNetCore.Authorization;
6+
using Microsoft.AspNetCore.Components.HotReload;
67

78
namespace Microsoft.AspNetCore.Components.Authorization;
89

910
internal static class AttributeAuthorizeDataCache
1011
{
12+
static AttributeAuthorizeDataCache()
13+
{
14+
if (HotReloadManager.Default.MetadataUpdateSupported)
15+
{
16+
HotReloadManager.Default.OnDeltaApplied += ClearCache;
17+
}
18+
}
19+
1120
private static readonly ConcurrentDictionary<Type, IAuthorizeData[]?> _cache = new();
1221

22+
private static void ClearCache() => _cache.Clear();
23+
1324
public static IAuthorizeData[]? GetAuthorizeDataForType(Type type)
1425
{
1526
if (!_cache.TryGetValue(type, out var result))

src/Components/Authorization/src/Microsoft.AspNetCore.Components.Authorization.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
<Reference Include="Microsoft.AspNetCore.Components" />
1515
</ItemGroup>
1616

17+
<ItemGroup>
18+
<Compile Include="$(ComponentsSharedSourceRoot)src\HotReloadManager.cs" LinkBase="HotReload" />
19+
</ItemGroup>
20+
1721
</Project>

src/Components/Components/src/BindConverter.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Reflection;
99
using System.Text;
1010
using System.Text.Json;
11+
using Microsoft.AspNetCore.Components.HotReload;
1112

1213
namespace Microsoft.AspNetCore.Components;
1314

@@ -1667,6 +1668,14 @@ private static class FormatterDelegateCache
16671668
{
16681669
private static readonly ConcurrentDictionary<Type, Delegate> _cache = new ConcurrentDictionary<Type, Delegate>();
16691670

1671+
static FormatterDelegateCache()
1672+
{
1673+
if (HotReloadManager.Default.MetadataUpdateSupported)
1674+
{
1675+
HotReloadManager.Default.OnDeltaApplied += _cache.Clear;
1676+
}
1677+
}
1678+
16701679
private static MethodInfo? _makeArrayFormatter;
16711680

16721681
[UnconditionalSuppressMessage(
@@ -1856,6 +1865,14 @@ internal static class ParserDelegateCache
18561865
{
18571866
private static readonly ConcurrentDictionary<Type, Delegate> _cache = new ConcurrentDictionary<Type, Delegate>();
18581867

1868+
static ParserDelegateCache()
1869+
{
1870+
if (HotReloadManager.Default.MetadataUpdateSupported)
1871+
{
1872+
HotReloadManager.Default.OnDeltaApplied += _cache.Clear;
1873+
}
1874+
}
1875+
18591876
private static MethodInfo? _convertToEnum;
18601877
private static MethodInfo? _convertToNullableEnum;
18611878
private static MethodInfo? _makeArrayTypeConverter;

src/Components/Components/src/ComponentFactory.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Concurrent;
55
using System.Diagnostics.CodeAnalysis;
66
using System.Reflection;
7+
using Microsoft.AspNetCore.Components.HotReload;
78
using Microsoft.AspNetCore.Components.Reflection;
89
using Microsoft.AspNetCore.Components.RenderTree;
910
using Microsoft.Extensions.DependencyInjection;
@@ -18,6 +19,14 @@ private const BindingFlags _injectablePropertyBindingFlags
1819

1920
private static readonly ConcurrentDictionary<Type, ComponentTypeInfoCacheEntry> _cachedComponentTypeInfo = new();
2021

22+
static ComponentFactory()
23+
{
24+
if (HotReloadManager.Default.MetadataUpdateSupported)
25+
{
26+
HotReloadManager.Default.OnDeltaApplied += ClearCache;
27+
}
28+
}
29+
2130
private readonly IComponentActivator _componentActivator;
2231
private readonly Renderer _renderer;
2332

src/Components/Components/src/DefaultComponentActivator.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Concurrent;
55
using System.Diagnostics.CodeAnalysis;
6+
using Microsoft.AspNetCore.Components.HotReload;
67
using Microsoft.Extensions.DependencyInjection;
78

89
namespace Microsoft.AspNetCore.Components;
@@ -11,6 +12,14 @@ internal sealed class DefaultComponentActivator(IServiceProvider serviceProvider
1112
{
1213
private static readonly ConcurrentDictionary<Type, ObjectFactory> _cachedComponentTypeInfo = new();
1314

15+
static DefaultComponentActivator()
16+
{
17+
if (HotReloadManager.Default.MetadataUpdateSupported)
18+
{
19+
HotReloadManager.Default.OnDeltaApplied += ClearCache;
20+
}
21+
}
22+
1423
public static void ClearCache() => _cachedComponentTypeInfo.Clear();
1524

1625
/// <inheritdoc />

src/Components/Components/src/PersistentState/PersistentServicesRegistry.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Reflection;
99
using System.Security.Cryptography;
1010
using System.Text;
11+
using Microsoft.AspNetCore.Components.HotReload;
1112
using Microsoft.AspNetCore.Components.Reflection;
1213
using Microsoft.AspNetCore.Internal;
1314
using Microsoft.Extensions.DependencyInjection;
@@ -24,6 +25,14 @@ internal sealed class PersistentServicesRegistry
2425
private List<PersistingComponentStateSubscription> _subscriptions = [];
2526
private static readonly ConcurrentDictionary<Type, PropertiesAccessor> _cachedAccessorsByType = new();
2627

28+
static PersistentServicesRegistry()
29+
{
30+
if (HotReloadManager.Default.MetadataUpdateSupported)
31+
{
32+
HotReloadManager.Default.OnDeltaApplied += _cachedAccessorsByType.Clear;
33+
}
34+
}
35+
2736
public PersistentServicesRegistry(IServiceProvider serviceProvider)
2837
{
2938
_serviceProvider = serviceProvider;

src/Components/Components/src/PersistentStateValueProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Reflection;
1010
using System.Security.Cryptography;
1111
using System.Text;
12+
using Microsoft.AspNetCore.Components.HotReload;
1213
using Microsoft.AspNetCore.Components.Reflection;
1314
using Microsoft.AspNetCore.Components.Rendering;
1415
using Microsoft.AspNetCore.Internal;
@@ -21,6 +22,20 @@ internal sealed class PersistentStateValueProvider(PersistentComponentState stat
2122
private static readonly ConcurrentDictionary<(Type, string), PropertyGetter> _propertyGetterCache = new();
2223
private static readonly ConcurrentDictionary<Type, IPersistentComponentStateSerializer?> _serializerCache = new();
2324

25+
static PersistentStateValueProvider()
26+
{
27+
if (HotReloadManager.Default.MetadataUpdateSupported)
28+
{
29+
HotReloadManager.Default.OnDeltaApplied += ClearCaches;
30+
}
31+
}
32+
33+
private static void ClearCaches()
34+
{
35+
_propertyGetterCache.Clear();
36+
_serializerCache.Clear();
37+
}
38+
2439
private readonly Dictionary<ComponentState, PersistingComponentStateSubscription> _subscriptions = [];
2540

2641
public bool IsFixed => false;

src/Components/Components/src/Reflection/ComponentProperties.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@
55
using System.Diagnostics.CodeAnalysis;
66
using System.Linq;
77
using System.Reflection;
8+
using Microsoft.AspNetCore.Components.HotReload;
89
using static Microsoft.AspNetCore.Internal.LinkerFlags;
910

1011
namespace Microsoft.AspNetCore.Components.Reflection;
1112

1213
internal static class ComponentProperties
1314
{
15+
static ComponentProperties()
16+
{
17+
if (HotReloadManager.Default.MetadataUpdateSupported)
18+
{
19+
HotReloadManager.Default.OnDeltaApplied += ClearCache;
20+
}
21+
}
22+
1423
internal const BindingFlags BindablePropertyFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase;
1524

1625
// Right now it's not possible for a component to define a Parameter and a Cascading Parameter with

src/Components/Components/src/RenderTree/EventArgsTypeCache.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33

44
using System.Collections.Concurrent;
55
using System.Reflection;
6+
using Microsoft.AspNetCore.Components.HotReload;
67

78
namespace Microsoft.AspNetCore.Components.RenderTree;
89

910
internal static class EventArgsTypeCache
1011
{
1112
private static readonly ConcurrentDictionary<MethodInfo, Type> Cache = new ConcurrentDictionary<MethodInfo, Type>();
1213

14+
static EventArgsTypeCache()
15+
{
16+
if (HotReloadManager.Default.MetadataUpdateSupported)
17+
{
18+
HotReloadManager.Default.OnDeltaApplied += Cache.Clear;
19+
}
20+
}
21+
1322
public static Type GetEventArgsType(MethodInfo methodInfo)
1423
{
1524
return Cache.GetOrAdd(methodInfo, methodInfo =>

src/Components/Components/src/Routing/RouteTable.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Concurrent;
55
using System.Diagnostics.CodeAnalysis;
66
using System.Globalization;
7+
using Microsoft.AspNetCore.Components.HotReload;
78
using Microsoft.AspNetCore.Routing.Tree;
89

910
namespace Microsoft.AspNetCore.Components.Routing;
@@ -13,6 +14,14 @@ internal sealed class RouteTable(TreeRouter treeRouter)
1314
private readonly TreeRouter _router = treeRouter;
1415
private static readonly ConcurrentDictionary<(Type, string), InboundRouteEntry> _routeEntryCache = new();
1516

17+
static RouteTable()
18+
{
19+
if (HotReloadManager.Default.MetadataUpdateSupported)
20+
{
21+
HotReloadManager.Default.OnDeltaApplied += _routeEntryCache.Clear;
22+
}
23+
}
24+
1625
public TreeRouter? TreeRouter => _router;
1726

1827
[UnconditionalSuppressMessage(

0 commit comments

Comments
 (0)