Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Dynamic;
11 : using System.Linq;
12 : using System.Reflection;
13 :
14 : namespace Cqrs.Infrastructure
15 : {
16 : internal class PrivateReflectionDynamicObject : DynamicObject
17 : {
18 : public object RealObject { get; set; }
19 : private const BindingFlags BindingFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic;
20 :
21 : internal static object WrapObjectIfNeeded(object @object)
22 : {
23 : // Don't wrap primitive types, which don't have many interesting internal APIs
24 : if (@object == null || @object.GetType().IsPrimitive || @object is string)
25 : return @object;
26 :
27 : return new PrivateReflectionDynamicObject { RealObject = @object };
28 : }
29 :
30 : // Called when a method is called
31 0 : public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
32 : {
33 : result = InvokeMemberOnType(RealObject.GetType(), RealObject, binder.Name, args);
34 :
35 : // Wrap the sub object if necessary. This allows nested anonymous objects to work.
36 : result = WrapObjectIfNeeded(result);
37 :
38 : return true;
39 : }
40 :
41 : private static object InvokeMemberOnType(Type type, object target, string name, object[] args)
42 : {
43 : try
44 : {
45 : if (type.GetMember(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Any())
46 : return type.InvokeMember(name, BindingFlags.InvokeMethod | BindingFlags, null, target, args);
47 : // If we couldn't find the method, try on the base class
48 : if (type.BaseType != null)
49 : return InvokeMemberOnType(type.BaseType, target, name, args);
50 : }
51 : catch (MissingMethodException)
52 : {
53 : // If we couldn't find the method, try on the base class
54 : if (type.BaseType != null)
55 : return InvokeMemberOnType(type.BaseType, target, name, args);
56 : }
57 : // Don't care if the method don't exist.
58 : return null;
59 : }
60 : }
61 : }
|