Documentation Coverage Report
Current view: top level - Cqrs/Infrastructure - PrivateReflectionDynamicObject.cs Hit Total Coverage
Version: 2.2 Artefacts: 1 1 100.0 %
Date: 2018-08-07 15:04:50

          Line data    Source code
       1             : #region Copyright
       2             : // // -----------------------------------------------------------------------
       3             : // // <copyright company="Chinchilla Software Limited">
       4             : // //   Copyright Chinchilla Software 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             :         /// <summary>
      17             :         /// A universal wrapper around complex and primitive objects.
      18             :         /// </summary>
      19             :         internal class PrivateReflectionDynamicObject : DynamicObject
      20             :         {
      21             :                 /// <summary>
      22             :                 /// The original/real <see cref="object"/> this wraps.
      23             :                 /// </summary>
      24             :                 public object RealObject { get; set; }
      25             : 
      26             :                 private const BindingFlags BindingFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic;
      27             : 
      28             :                 internal static object WrapObjectIfNeeded(object @object)
      29             :                 {
      30             :                         // Don't wrap primitive types, which don't have many interesting internal APIs
      31             :                         if (@object == null || @object.GetType().IsPrimitive || @object is string)
      32             :                                 return @object;
      33             : 
      34             :                         return new PrivateReflectionDynamicObject { RealObject = @object };
      35             :                 }
      36             : 
      37             :                 /// <summary>
      38             :                 /// Calls <see cref="InvokeMemberOnType"/> then passes the response to <see cref="WrapObjectIfNeeded"/>.
      39             :                 /// </summary>
      40             :                 /// <remarks>Called when a method is called.</remarks>
      41           1 :                 public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
      42             :                 {
      43             :                         result = InvokeMemberOnType(RealObject.GetType(), RealObject, binder.Name, args);
      44             : 
      45             :                         // Wrap the sub object if necessary. This allows nested anonymous objects to work.
      46             :                         result = WrapObjectIfNeeded(result);
      47             : 
      48             :                         return true;
      49             :                 }
      50             : 
      51             :                 private static object InvokeMemberOnType(Type type, object target, string name, object[] args)
      52             :                 {
      53             :                         try
      54             :                         {
      55             :                                 if (type.GetMember(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Any())
      56             :                                         return type.InvokeMember(name, BindingFlags.InvokeMethod | BindingFlags, null, target, args);
      57             :                                 // If we couldn't find the method, try on the base class
      58             :                                 if (type.BaseType != null)
      59             :                                         return InvokeMemberOnType(type.BaseType, target, name, args);
      60             :                         }
      61             :                         catch (MissingMethodException)
      62             :                         {
      63             :                                 // If we couldn't find the method, try on the base class
      64             :                                 if (type.BaseType != null)
      65             :                                         return InvokeMemberOnType(type.BaseType, target, name, args);
      66             :                         }
      67             :                                 // Don't care if the method don't exist.
      68             :                         return null;
      69             :                 }
      70             :         }
      71             : }

Generated by: LCOV version 1.12