Skip to content
This repository was archived by the owner on Jun 8, 2025. It is now read-only.

Commit 62fe5a3

Browse files
committed
Add property getter cache.
1 parent fef9a6e commit 62fe5a3

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

Source/Singulink.Text.TokenFormatter/Singulink.Text.TokenFormatter.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<Company>Singulink</Company>
1313
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1414
<Copyright>Copyright (c) 2020 Singulink</Copyright>
15+
<Version>1.0.1</Version>
1516
</PropertyGroup>
1617

1718
<ItemGroup>

Source/Singulink.Text.TokenFormatter/TokenFormatter.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections;
3+
using System.Collections.Concurrent;
34
using System.Collections.Generic;
45
using System.Reflection;
56
using System.Text;
@@ -27,6 +28,23 @@ namespace Singulink.Text
2728
/// </remarks>
2829
public static class TokenFormatter
2930
{
31+
#region Property Getter Cache
32+
33+
private static readonly ConcurrentDictionary<(Type Type, string PropertyName, bool NonPublic), MethodInfo?> _getterCache =
34+
new ConcurrentDictionary<(Type, string, bool), MethodInfo?>();
35+
36+
private static readonly Func<(Type Type, string PropertyName, bool NonPublic), MethodInfo?> _getterFactory = key => {
37+
var bindingFlags = BindingFlags.Instance | BindingFlags.Public;
38+
39+
if (key.NonPublic)
40+
bindingFlags |= BindingFlags.NonPublic;
41+
42+
var property = key.Type.GetProperty(key.PropertyName, bindingFlags);
43+
return property?.GetGetMethod(key.NonPublic);
44+
};
45+
46+
#endregion
47+
3048
/// <summary>
3149
/// Substitutes named tokens in the format string with values provided from a dictionary or an object.
3250
/// </summary>
@@ -141,15 +159,10 @@ static bool ResolveTokenSubValue(string tokenKeyName, object currentValue, bool
141159
return false;
142160
}
143161

144-
var bindingFlags = BindingFlags.Instance | BindingFlags.Public;
145-
146-
if (nonPublic)
147-
bindingFlags |= BindingFlags.NonPublic;
148-
149-
var property = currentValue.GetType().GetProperty(tokenKeyName, bindingFlags);
162+
var getter = _getterCache.GetOrAdd((currentValue.GetType(), tokenKeyName, nonPublic), _getterFactory);
150163

151-
if (property?.CanRead == true) {
152-
value = property.GetValue(currentValue);
164+
if (getter != null) {
165+
value = getter.Invoke(currentValue, null);
153166
return true;
154167
}
155168

0 commit comments

Comments
 (0)