Skip to content

Commit 4f9e2b8

Browse files
author
Michael Pham
committed
Reflection caching added to the various reflection classes.
1 parent 2e85897 commit 4f9e2b8

File tree

4 files changed

+58
-62
lines changed

4 files changed

+58
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
namespace NativeCode.Mobile.AppCompat.Renderers.Extensions
22
{
33
using System;
4-
using System.Linq;
4+
using System.Reflection;
5+
6+
using NativeCode.Mobile.AppCompat.Renderers.Helpers;
57

68
using Xamarin.Forms;
79

@@ -10,10 +12,21 @@ namespace NativeCode.Mobile.AppCompat.Renderers.Extensions
1012
/// </summary>
1113
public static class ElementExtensions
1214
{
13-
private const string ButtonController = "IButtonController";
15+
private const string ButtonControllerType = "Xamarin.Forms.IButtonController, Xamarin.Forms.Core";
1416

1517
private const string ButtonControllerSendClicked = "SendClicked";
1618

19+
private static readonly MethodInfo MethodSendClicked;
20+
21+
/// <summary>
22+
/// Initializes static members of the <see cref="ElementExtensions"/> class.
23+
/// </summary>
24+
static ElementExtensions()
25+
{
26+
var type = Type.GetType(ButtonControllerType, true);
27+
MethodSendClicked = type.GetMethod(ButtonControllerSendClicked);
28+
}
29+
1730
/// <summary>
1831
/// Tries to cast the element to a button controller and invoke the SendClicked method.
1932
/// </summary>
@@ -22,27 +35,7 @@ public static class ElementExtensions
2235
/// <remarks>The IButtonController is an internal interface, so we have to use reflection.</remarks>
2336
public static void InvokeSendClicked(this Element element)
2437
{
25-
var type = GetImplementedInterface(element, ButtonController);
26-
var method = type.GetMethod(ButtonControllerSendClicked);
27-
28-
if (method == null)
29-
{
30-
throw new MissingMethodException(type.Name, ButtonControllerSendClicked);
31-
}
32-
33-
method.Invoke(element, new object[0]);
34-
}
35-
36-
private static Type GetImplementedInterface(object instance, string name)
37-
{
38-
var type = instance.GetType().GetInterfaces().Single(x => x.Name == ButtonController);
39-
40-
if (type == null)
41-
{
42-
throw new InvalidCastException("Type does not implement interface " + name + ".");
43-
}
44-
45-
return type;
38+
MethodSendClicked.Invoke(element, ReflectionHelper.EmptyParameters);
4639
}
4740
}
4841
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
namespace NativeCode.Mobile.AppCompat.Renderers.Extensions
22
{
3-
using System;
43
using System.Reflection;
54

5+
using NativeCode.Mobile.AppCompat.Renderers.Helpers;
6+
67
using Xamarin.Forms;
78

89
/// <summary>
@@ -12,21 +13,26 @@ public static class EntryExtensions
1213
{
1314
private const string EntrySendCompleted = "SendCompleted";
1415

16+
private const BindingFlags InstanceNonPublic = BindingFlags.Instance | BindingFlags.NonPublic;
17+
18+
private static readonly MethodInfo MethodSendCompleted;
19+
20+
/// <summary>
21+
/// Initializes static members of the <see cref="EntryExtensions"/> class.
22+
/// </summary>
23+
static EntryExtensions()
24+
{
25+
var type = typeof(Entry);
26+
MethodSendCompleted = type.GetMethod(EntrySendCompleted, InstanceNonPublic);
27+
}
28+
1529
/// <summary>
1630
/// Invokes the send completed.
1731
/// </summary>
1832
/// <param name="entry">The entry.</param>
1933
public static void InvokeSendCompleted(this Entry entry)
2034
{
21-
var type = entry.GetType();
22-
var method = type.GetMethod(EntrySendCompleted, BindingFlags.Instance | BindingFlags.NonPublic);
23-
24-
if (method == null)
25-
{
26-
throw new MissingMethodException(type.Name, EntrySendCompleted);
27-
}
28-
29-
method.Invoke(entry, new object[0]);
35+
MethodSendCompleted.Invoke(entry, ReflectionHelper.EmptyParameters);
3036
}
3137
}
3238
}

src/NativeCode.Mobile.AppCompat.Renderers/Helpers/KeyboardHelper.cs

+24-29
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,50 @@ namespace NativeCode.Mobile.AppCompat.Renderers.Helpers
1111

1212
internal static class KeyboardHelper
1313
{
14-
private const string KeyboardExtensions = "Xamarin.Forms.Platform.Android.KeyboardExtensions, Xamarin.Forms.Platform.Android";
14+
private const string KeyboardExtensionsType = "Xamarin.Forms.Platform.Android.KeyboardExtensions, Xamarin.Forms.Platform.Android";
1515

1616
private const string KeyboardExtensionsToInputType = "ToInputType";
1717

18-
private const string KeyboardManager = "Xamarin.Forms.Platform.Android.KeyboardManager, Xamarin.Forms.Platform.Android";
18+
private const string KeyboardManagerType = "Xamarin.Forms.Platform.Android.KeyboardManager, Xamarin.Forms.Platform.Android";
1919

2020
private const string KeyboardManagerHideKeyboard = "HideKeyboard";
2121

2222
private const string KeyboardManagerShowKeyboard = "ShowKeyboard";
2323

24-
private const BindingFlags StaticMethodBindingFlags = BindingFlags.NonPublic | BindingFlags.Static;
24+
private const BindingFlags StaticInternalMethods = BindingFlags.NonPublic | BindingFlags.Static;
2525

26-
public static InputTypes GetInputType(Keyboard keyboard)
26+
private static readonly MethodInfo MethodToInputType;
27+
28+
private static readonly MethodInfo MethodHideKeyboard;
29+
30+
private static readonly MethodInfo MethodShowKeyboard;
31+
32+
/// <summary>
33+
/// Initializes static members of the <see cref="KeyboardHelper"/> class.
34+
/// </summary>
35+
static KeyboardHelper()
2736
{
28-
var type = Type.GetType(KeyboardExtensions, true);
29-
var method = type.GetMethod(KeyboardExtensionsToInputType);
37+
var keyboardExtensionsType = Type.GetType(KeyboardExtensionsType, true);
38+
MethodToInputType = keyboardExtensionsType.GetMethod(KeyboardExtensionsToInputType);
3039

31-
if (method == null)
32-
{
33-
throw new MissingMethodException(type.Name, KeyboardExtensionsToInputType);
34-
}
40+
var keyboardManagerType = Type.GetType(KeyboardManagerType, true);
41+
MethodHideKeyboard = keyboardManagerType.GetMethod(KeyboardManagerHideKeyboard, StaticInternalMethods);
42+
MethodShowKeyboard = keyboardManagerType.GetMethod(KeyboardManagerShowKeyboard, StaticInternalMethods);
43+
}
3544

36-
return (InputTypes)method.Invoke(null, new object[] { keyboard });
45+
public static InputTypes GetInputType(Keyboard keyboard)
46+
{
47+
return (InputTypes)MethodToInputType.Invoke(null, new object[] { keyboard });
3748
}
3849

3950
public static void HideKeyboard(View view)
4051
{
41-
var type = Type.GetType(KeyboardManager, true);
42-
var method = type.GetMethod(KeyboardManagerHideKeyboard, StaticMethodBindingFlags);
43-
44-
if (method == null)
45-
{
46-
throw new MissingMethodException(type.Name, KeyboardManagerHideKeyboard);
47-
}
48-
49-
method.Invoke(null, new object[] { view });
52+
MethodHideKeyboard.Invoke(null, new object[] { view });
5053
}
5154

5255
public static void ShowKeyboard(View view)
5356
{
54-
var type = Type.GetType(KeyboardManager, true);
55-
var method = type.GetMethod(KeyboardManagerShowKeyboard, StaticMethodBindingFlags);
56-
57-
if (method == null)
58-
{
59-
throw new MissingMethodException(type.Name, KeyboardManagerShowKeyboard);
60-
}
61-
62-
method.Invoke(null, new object[] { view });
57+
MethodShowKeyboard.Invoke(null, new object[] { view });
6358
}
6459
}
6560
}

src/NativeCode.Mobile.AppCompat.Renderers/Helpers/ReflectionHelper.cs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace NativeCode.Mobile.AppCompat.Renderers.Helpers
55

66
internal static class ReflectionHelper
77
{
8+
public static readonly object[] EmptyParameters = new object[0];
9+
810
public static void SetFieldValue(object instance, string name, object value)
911
{
1012
var field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);

0 commit comments

Comments
 (0)