master 3b0ecb222cc8 cached
25 files
61.9 KB
14.1k tokens
123 symbols
1 requests
Download .txt
Repository: ReflectionMagic/ReflectionMagic
Branch: master
Commit: 3b0ecb222cc8
Files: 25
Total size: 61.9 KB

Directory structure:
gitextract_3o09ty_o/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── README.md
├── ReflectionMagic.sln
├── ReflectionMagic.snk
├── build-nuget.cmd
├── build.ps1
├── src/
│   └── ReflectionMagic/
│       ├── DynamicHelper.cs
│       ├── Field.cs
│       ├── IProperty.cs
│       ├── PrivateReflectionDynamicObjectBase.cs
│       ├── PrivateReflectionDynamicObjectInstance.cs
│       ├── PrivateReflectionDynamicObjectStatic.cs
│       ├── PrivateReflectionUsingDynamicExtensions.cs
│       ├── Property.cs
│       └── ReflectionMagic.csproj
└── test/
    ├── LibraryWithPrivateMembers/
    │   ├── LibraryWithPrivateMembers.csproj
    │   └── MiscTestClasses.cs
    └── ReflectionMagicTests/
        ├── ConstructorSelectionTests.cs
        ├── ExtensionMethodFacts.cs
        ├── ReflectionMagicTests.csproj
        └── UnitTest.cs

================================================
FILE CONTENTS
================================================

================================================
FILE: .config/dotnet-tools.json
================================================
{
  "version": 1,
  "isRoot": true,
  "tools": {
    "dotnet-validate": {
      "version": "0.0.1-preview.304",
      "commands": [
        "dotnet-validate"
      ]
    }
  }
}

================================================
FILE: .editorconfig
================================================
# editorconfig.org

# top-most EditorConfig file
root = true

# Default settings:
# A newline ending every file
# Use 4 spaces as indentation
[*]
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = crlf

# C#
[*.cs]
indent_size = 4

[project.json]
indent_size = 4


================================================
FILE: .gitattributes
================================================
# 
*    text=auto
*.cs diff=csharp

# Solutions and projects should use windows line endings
*.sln    text eol=crlf
*.csproj text eol=crlf
*.fsproj text eol=crlf
*.dbproj text eol=crlf

================================================
FILE: .gitignore
================================================
bin
obj
Packages
TestResults
*.csproj.user
*.vsp
*.psess
*.suo
*.nupkg
*.user

.vs

project.lock.json

================================================
FILE: LICENSE.txt
================================================
 
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/
 
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
   1. Definitions.
 
      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.
 
      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.
 
      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.
 
      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.
 
      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.
 
      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.
 
      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).
 
      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.
 
      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."
 
      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.
 
   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.
 
   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.
 
   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:
 
      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and
 
      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and
 
      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and
 
      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.
 
      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.
 
   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.
 
   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.
 
   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.
 
   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.
 
   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.
 
   END OF TERMS AND CONDITIONS


================================================
FILE: README.md
================================================
# ReflectionMagic
[![Build Status](https://dev.azure.com/jvandertil/OpenSource/_apis/build/status/github/ReflectionMagic/ReflectionMagic/Continuous%20Integration?branchName=master)](https://dev.azure.com/jvandertil/OpenSource/_build/latest?definitionId=3&branchName=master)

Private reflection allows you to access private and internal members in other assemblies.  Generally, it’s considered to be a bad thing to do, as it ties you to undocumented implementation details which can later break you.  Also, it’s not usable in medium trust.

The purpose of this library is not to encourage anyone to use private reflection in situations where you would not have done it anyway.  Instead, the purpose is to allow you to do it much more easily if you decide that you need to use it. 

_Putting it a different way, I’m not telling you to break the law, but I’m telling you how to break the law more efficiently if that’s what you’re into!_

## The scenario

Assume you are using an assembly that has code like this:

```cs
public class Foo1 
{
    private Foo2 GetOtherClass() 
    { 
        // Omitted
    }
}

internal class Foo2 
{
    private string SomeProp { get { /* Omitted */ } }
}
```
And assume you have an instance _foo1_ of the public class Foo1 and your evil self tells you that you want to call the private method _GetOtherClass()_ and then get the _SomeProp_ property off that.

### Using reflection
Using plain old reflection this would be something like this:

```cs
object foo2 = typeof(Foo1).InvokeMember("GetOtherClass", 
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                null, foo1, null);
                
PropertyInfo propInfo = foo2.GetType().GetProperty("SomeProp",    
                BindingFlags.Instance | BindingFlags.NonPublic);

string val = (string)propInfo.GetValue(foo2, null);
```
Which works, but is pretty ugly.

### Using ReflectionMagic
Doing the same but using the ReflectionMagic library:
```cs
string val = foo1.AsDynamic().GetOtherClass().SomeProp;
```

## Download

This library is available through [NuGet](https://www.nuget.org/packages/ReflectionMagic).

## More info

For more information look at the original blog post by David Ebbo: https://blogs.msdn.microsoft.com/davidebb/2010/01/18/use-c-4-0-dynamic-to-drastically-simplify-your-private-reflection-code/

## Known limitations
Support for 'out' and 'ref' parameters is not available on .NET Core 1.x runtimes. This is a runtime limitation and results in a PlatformNotSupportedException.


================================================
FILE: ReflectionMagic.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8F82B878-92C3-4982-9C7B-9F877352010D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EFD11FC-DE26-4864-A678-B06E9C78463E}"
	ProjectSection(SolutionItems) = preProject
		ReflectionMagic.snk = ReflectionMagic.snk
		build.ps1 = build.ps1
		build-nuget.cmd = build-nuget.cmd
		global.json = global.json
	EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{104DADBE-0311-418B-AC13-10E36B66EC1D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReflectionMagic", "src\ReflectionMagic\ReflectionMagic.csproj", "{3C576B3B-09A9-49A6-A698-5B693C0005CC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReflectionMagicTests", "test\ReflectionMagicTests\ReflectionMagicTests.csproj", "{BAED5E4B-82E7-4317-B835-9EE289A25923}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryWithPrivateMembers", "test\LibraryWithPrivateMembers\LibraryWithPrivateMembers.csproj", "{AFAC595E-BB9A-42A6-88FD-750BC6454224}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{3C576B3B-09A9-49A6-A698-5B693C0005CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{3C576B3B-09A9-49A6-A698-5B693C0005CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{3C576B3B-09A9-49A6-A698-5B693C0005CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{3C576B3B-09A9-49A6-A698-5B693C0005CC}.Release|Any CPU.Build.0 = Release|Any CPU
		{BAED5E4B-82E7-4317-B835-9EE289A25923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{BAED5E4B-82E7-4317-B835-9EE289A25923}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{BAED5E4B-82E7-4317-B835-9EE289A25923}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{BAED5E4B-82E7-4317-B835-9EE289A25923}.Release|Any CPU.Build.0 = Release|Any CPU
		{AFAC595E-BB9A-42A6-88FD-750BC6454224}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{AFAC595E-BB9A-42A6-88FD-750BC6454224}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AFAC595E-BB9A-42A6-88FD-750BC6454224}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AFAC595E-BB9A-42A6-88FD-750BC6454224}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(NestedProjects) = preSolution
		{3C576B3B-09A9-49A6-A698-5B693C0005CC} = {8F82B878-92C3-4982-9C7B-9F877352010D}
		{BAED5E4B-82E7-4317-B835-9EE289A25923} = {104DADBE-0311-418B-AC13-10E36B66EC1D}
		{AFAC595E-BB9A-42A6-88FD-750BC6454224} = {104DADBE-0311-418B-AC13-10E36B66EC1D}
	EndGlobalSection
EndGlobal


================================================
FILE: build-nuget.cmd
================================================
@echo off
IF "%Configuration%"=="" (SET Configuration=Release)
IF "%Configuration%"=="Release" (SET ContinuousIntegrationBuild=true)
echo Starting build in %Configuration% mode (ContinuousIntegrationBuild=%ContinuousIntegrationBuild%).

dotnet clean
dotnet restore
dotnet build --no-restore
dotnet test --no-build
dotnet pack --no-build

set Configuration=
set ContinuousIntegrationBuild=

dotnet tool restore
dotnet validate package local **\*.nupkg


================================================
FILE: build.ps1
================================================
param (
    [string]$OutputDirectory = $PSScriptRoot,
    [string]$TestResultOutputDirectory = (Join-Path $PSScriptRoot "TestResults"),
    [string]$VersionSuffix = "local",
    [string]$BuildConfiguration = "Release"
)

# Taken from psake https://github.com/psake/psake

<#
.SYNOPSIS
  This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
  to see if an error occcured. If an error is detected then an exception is thrown.
  This function allows you to run command-line programs without having to
  explicitly check the $lastexitcode variable.
.EXAMPLE
  exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd)
    )
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)
    }
}

exec { & dotnet clean --configuration $BuildConfiguration }
exec { & dotnet restore }
exec { & dotnet build --configuration $BuildConfiguration /p:VersionSuffix="$VersionSuffix" }
exec { & dotnet test --results-directory $TestResultOutputDirectory --logger trx --no-build --verbosity=normal --configuration $BuildConfiguration ./test/ReflectionMagicTests/ReflectionMagicTests.csproj }
exec { & dotnet pack --no-build /p:VersionSuffix="$VersionSuffix" --configuration $BuildConfiguration --output $OutputDirectory --include-symbols src/ReflectionMagic }

================================================
FILE: src/ReflectionMagic/DynamicHelper.cs
================================================
namespace ReflectionMagic
{
    public static class DynamicHelper
    {
        /// <summary>
        /// Unwraps the specified dynamic object.
        /// </summary>
        /// <param name="d">A wrapped object</param>
        /// <returns>The unwrapped object.</returns>
        /// <seealso cref="PrivateReflectionDynamicObjectInstance.RealObject"/>
        /// <seealso cref="PrivateReflectionDynamicObjectStatic.RealObject"/>
        public static object Unwrap(dynamic d)
        {
            // If it's a wrapped object, unwrap it and return the real thing.
            if (d is PrivateReflectionDynamicObjectBase wrapper)
                return wrapper.RealObject;

            // Otherwise, return it unchanged.
            return d;
        }
    }
}


================================================
FILE: src/ReflectionMagic/Field.cs
================================================
using System;
using System.Reflection;

namespace ReflectionMagic
{
    /// <summary>
    /// Provides a mechanism to access fields through the <see cref="IProperty"/> abstraction.
    /// </summary>
    internal class Field : IProperty
    {
        private readonly FieldInfo _fieldInfo;

        /// <summary>
        /// Initializes a new instance of the <see cref="Field"/> class wrapping the specified field.
        /// </summary>
        /// <param name="field">The field info to wrap.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="field"/> is <c>null</c>.</exception>
        internal Field(FieldInfo field)
        {
            _fieldInfo = field ?? throw new ArgumentNullException(nameof(field));
        }

        public Type PropertyType => _fieldInfo.FieldType;

        string IProperty.Name => _fieldInfo.Name;

        object IProperty.GetValue(object obj, object[] index)
        {
            return _fieldInfo.GetValue(obj);
        }

        void IProperty.SetValue(object obj, object value, object[] index)
        {
            _fieldInfo.SetValue(obj, value);
        }
    }
}


================================================
FILE: src/ReflectionMagic/IProperty.cs
================================================
using System;

namespace ReflectionMagic
{
    /// <summary>
    /// Defines an mechanism to access members (e.g. fields or properties) of objects in a consistent way.
    /// </summary>
    public interface IProperty
    {
        /// <summary>
        /// Gets the name of the property.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Gets the type of the property.
        /// </summary>
        Type PropertyType { get; }

        /// <summary>
        /// Returns the property value of a specified object with optional index values for indexed properties.
        /// </summary>
        /// <param name="obj">The object whose property value will be returned. </param>
        /// <param name="index">Optional index values for indexed properties. The indexes of indexed properties are zero-based. This value should be null for non-indexed properties. </param>
        /// <returns>The member value of the specified object.</returns>
        object GetValue(object obj, object[] index);

        /// <summary>
        /// Sets the property value of a specified object with optional index values for index properties.
        /// </summary>
        /// <param name="obj">The object whose property value will be set. </param>
        /// <param name="value">The new property value. </param>
        /// <param name="index">Optional index values for indexed properties. This value should be null for non-indexed properties. </param>
        void SetValue(object obj, object value, object[] index);
    }
}


================================================
FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectBase.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Reflection;

namespace ReflectionMagic
{
    public abstract class PrivateReflectionDynamicObjectBase : DynamicObject
    {
        // We need to virtualize this so we use a different cache for instance and static props
        protected abstract IDictionary<Type, IDictionary<string, IProperty>> PropertiesOnType { get; }

        protected abstract Type TargetType { get; }

        protected abstract object Instance { get; }

        protected abstract BindingFlags BindingFlags { get; }

        public abstract object RealObject { get; }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            IProperty prop = GetProperty(binder.Name);

            // Get the property value
            result = prop.GetValue(Instance, index: null);

            // Wrap the sub object if necessary. This allows nested anonymous objects to work.
            result = result.AsDynamic();

            return true;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            IProperty prop = GetProperty(binder.Name);

            // Set the property value.  Make sure to unwrap it first if it's one of our dynamic objects
            prop.SetValue(Instance, DynamicHelper.Unwrap(value), index: null);

            return true;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            IProperty prop = GetIndexProperty();
            result = prop.GetValue(Instance, indexes);

            // Wrap the sub object if necessary. This allows nested anonymous objects to work.
            result = result.AsDynamic();

            return true;
        }

        public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            IProperty prop = GetIndexProperty();
            prop.SetValue(Instance, DynamicHelper.Unwrap(value), indexes);

            return true;
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            if (args is null)
                throw new ArgumentNullException(nameof(args));

            for (int i = 0; i < args.Length; i++)
            {
                args[i] = DynamicHelper.Unwrap(args[i]);
            }

            var typeArgs = GetGenericMethodArguments(binder);

            result = InvokeMethodOnType(TargetType, Instance, binder.Name, args, typeArgs);

            // Wrap the sub object if necessary. This allows nested anonymous objects to work.
            result = result.AsDynamic();

            return true;
        }

        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            if (binder is null)
                throw new ArgumentNullException(nameof(binder));

            result = binder.Type.IsInstanceOfType(RealObject) ? RealObject : Convert.ChangeType(RealObject, binder.Type);

            return true;
        }

        public override string ToString()
        {
            Debug.Assert(Instance != null);

            return Instance.ToString();
        }

        private IProperty GetIndexProperty()
        {
            // The index property is always named "Item" in C#
            return GetProperty("Item");
        }

        private IProperty GetProperty(string propertyName)
        {
            // Get the list of properties and fields for this type
            IDictionary<string, IProperty> typeProperties = GetTypeProperties(TargetType);

            // Look for the one we want
            if (typeProperties.TryGetValue(propertyName, out IProperty property))
                return property;

            // The property doesn't exist

            // Get a list of supported properties and fields and show them as part of the exception message
            // For fields, skip the auto property backing fields (which name start with <)
            var propNames = typeProperties.Keys.Where(name => name[0] != '<').OrderBy(name => name);

            throw new MissingMemberException(
                $"The property {propertyName} doesn\'t exist on type {TargetType}. Supported properties are: {string.Join(", ", propNames)}");
        }

        private IDictionary<string, IProperty> GetTypeProperties(Type type)
        {
            // First, check if we already have it cached
            if (PropertiesOnType.TryGetValue(type, out IDictionary<string, IProperty> typeProperties))
                return typeProperties;

            // Not cached, so we need to build it
            typeProperties = new Dictionary<string, IProperty>();

            // First, recurse on the base class to add its fields
            if (!(type.BaseType is null))
            {
                foreach (IProperty prop in GetTypeProperties(type.BaseType).Values)
                {
                    typeProperties[prop.Name] = prop;
                }
            }

            // Then, add all the properties from the current type
            foreach (PropertyInfo prop in type.GetProperties(BindingFlags))
            {
                if (prop.DeclaringType == type)
                {
                    typeProperties[prop.Name] = new Property(prop);
                }
            }

            // Finally, add all the fields from the current type
            foreach (FieldInfo field in type.GetFields(BindingFlags))
            {
                if (field.DeclaringType == type)
                {
                    typeProperties[field.Name] = new Field(field);
                }
            }

            // Cache it for next time
            PropertiesOnType[type] = typeProperties;

            return typeProperties;
        }

        private static bool ParametersCompatible(MethodInfo method, object[] passedArguments)
        {
            Debug.Assert(method != null);
            Debug.Assert(passedArguments != null);

            var parametersOnMethod = method.GetParameters();

            if (parametersOnMethod.Length != passedArguments.Length)
                return false;

            for (int i = 0; i < parametersOnMethod.Length; ++i)
            {
                var parameterType = parametersOnMethod[i].ParameterType;
                ref var argument = ref passedArguments[i];

                if (argument is null && parameterType.IsValueType)
                {
                    // Value types can not be null.
                    return false;
                }

                if (!parameterType.IsInstanceOfType(argument))
                {
                    // Parameters should be instance of the parameter type.
                    if (parameterType.IsByRef)
                    {
                        var typePassedByRef = parameterType.GetElementType();

                        Debug.Assert(typePassedByRef != null);

                        if (typePassedByRef.IsValueType && argument is null)
                        {
                            return false;
                        }

                        if (!(argument is null))
                        {
                            var argumentType = argument.GetType();
                            var argumentByRefType = argumentType.MakeByRefType();
                            if (parameterType != argumentByRefType)
                            {
                                try
                                {
                                    argument = Convert.ChangeType(argument, typePassedByRef);
                                }
                                catch (InvalidCastException)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                    else if (argument is null)
                    {
                        continue;
                    }
                    else
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        private static object InvokeMethodOnType(Type type, object target, string name, object[] args, Type[] typeArgs)
        {
            Debug.Assert(type != null);
            Debug.Assert(args != null);
            Debug.Assert(typeArgs != null);

            const BindingFlags allMethods =
                BindingFlags.Public | BindingFlags.NonPublic
                | BindingFlags.Instance | BindingFlags.Static;

            MethodInfo method = null;
            Type currentType = type;

            while (method is null && !(currentType is null))
            {
                var methods = currentType.GetMethods(allMethods);

                MethodInfo candidate;
                for (int i = 0; i < methods.Length; ++i)
                {
                    candidate = methods[i];

                    if (candidate.Name == name)
                    {
                        // Check if the method is called as a generic method.
                        if (typeArgs.Length > 0 && candidate.ContainsGenericParameters)
                        {
                            var candidateTypeArgs = candidate.GetGenericArguments();
                            if (candidateTypeArgs.Length == typeArgs.Length)
                            {
                                candidate = candidate.MakeGenericMethod(typeArgs);
                            }
                        }

                        if (ParametersCompatible(candidate, args))
                        {
                            method = candidate;
                            break;
                        }
                    }
                }

                if (method is null)
                {
                    // Move up in the type hierarchy.
                    // If there is no base type, then this will set currentType to null, terminating the loop.
                    currentType = currentType.BaseType;
                }
            }

            if (method is null)
            {
                throw new MissingMethodException($"Method with name '{name}' not found on type '{type.FullName}'.");
            }

            return method.Invoke(target, args);
        }

        private static Type[] GetGenericMethodArguments(InvokeMemberBinder binder)
        {
            var csharpInvokeMemberBinderType = binder
                    .GetType()
                    .GetInterface("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder")
                    ;

            var typeArgsList = (IList<Type>)csharpInvokeMemberBinderType.GetProperty("TypeArguments").GetValue(binder, null);

            Type[] typeArgs;
            if (typeArgsList.Count == 0)
            {
                typeArgs = Array.Empty<Type>();
            }
            else
            {
                typeArgs = typeArgsList.ToArray();
            }

            return typeArgs;
        }
    }
}


================================================
FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectInstance.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;

namespace ReflectionMagic
{
    public class PrivateReflectionDynamicObjectInstance : PrivateReflectionDynamicObjectBase
    {
        private static readonly ConcurrentDictionary<Type, IDictionary<string, IProperty>> _propertiesOnType = new();

        private readonly object _instance;

        /// <summary>
        /// Initializes a new instance of the <see cref="PrivateReflectionDynamicObjectInstance"/> class, wrapping the specified object.
        /// </summary>
        /// <param name="instance">The object to wrap.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="instance"/> is <c>null</c>.</exception>
        public PrivateReflectionDynamicObjectInstance(object instance)
        {
            _instance = instance ?? throw new ArgumentNullException(nameof(instance));
        }

        protected override IDictionary<Type, IDictionary<string, IProperty>> PropertiesOnType => _propertiesOnType;

        // For instance calls, we get the type from the instance
        protected override Type TargetType => _instance.GetType();

        protected override object Instance => _instance;

        /// <summary>
        /// The object that the <see cref="PrivateReflectionDynamicObjectInstance"/> wraps.
        /// </summary>
        public override object RealObject => Instance;

        protected override BindingFlags BindingFlags => BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    }
}


================================================
FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectStatic.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

namespace ReflectionMagic
{
    public class PrivateReflectionDynamicObjectStatic : PrivateReflectionDynamicObjectBase
    {
        private static readonly ConcurrentDictionary<Type, IDictionary<string, IProperty>> _propertiesOnType = new();

        /// <summary>
        /// Initializes a new instance of the <see cref="PrivateReflectionDynamicObjectStatic"/> class, wrapping the specified type.
        /// </summary>
        /// <param name="type">The type to wrap.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="type"/> is <c>null</c>.</exception>
        public PrivateReflectionDynamicObjectStatic(Type type)
        {
            TargetType = type ?? throw new ArgumentNullException(nameof(type));
        }

        protected override IDictionary<Type, IDictionary<string, IProperty>> PropertiesOnType => _propertiesOnType;

        // For static calls, we have the type and the instance is always null
        protected override Type TargetType { get; }

        protected override object Instance => null;

        /// <summary>
        /// The type that the <see cref="PrivateReflectionDynamicObjectStatic"/> wraps.
        /// </summary>
        public override object RealObject => TargetType;

        protected override BindingFlags BindingFlags => BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

        public dynamic New(params object[] args)
        {
            if (args is null)
                throw new ArgumentNullException(nameof(args));

            Debug.Assert(TargetType != null);

            return Activator.CreateInstance(TargetType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, args, null).AsDynamic();
        }
    }
}


================================================
FILE: src/ReflectionMagic/PrivateReflectionUsingDynamicExtensions.cs
================================================
using System;
using System.Reflection;

namespace ReflectionMagic
{
    public static class PrivateReflectionUsingDynamicExtensions
    {
        /// <summary>
        /// Wraps the specified object in a dynamic object that allows access to private members.
        /// </summary>
        /// <param name="o">The object to wrap</param>
        /// <returns>The wrapped object.</returns>
        /// <remarks>
        /// Does not wrap <c>null</c>, <see cref="string"/>, primitive types, and already wrapped objects.
        /// </remarks>
        /// <seealso cref="PrivateReflectionDynamicObjectInstance"/>
        public static dynamic AsDynamic(this object o)
        {
            // Don't wrap primitive types, which don't have many interesting internal APIs
            if (o is null || o.GetType().IsPrimitive || o is string || o is PrivateReflectionDynamicObjectBase)
                return o;

            return new PrivateReflectionDynamicObjectInstance(o);
        }

        /// <summary>
        /// Wraps the specified type in a dynamic object which allows easy instantion through the <see cref="PrivateReflectionDynamicObjectStatic.New"/> method.
        /// </summary>
        /// <param name="type">The type to wrap.</param>
        /// <returns>The wrapped type.</returns>
        /// <seealso cref="PrivateReflectionDynamicObjectStatic"/>
        public static dynamic AsDynamicType(this Type type)
        {
            return new PrivateReflectionDynamicObjectStatic(type);
        }

        /// <summary>
        /// Gets the type with the specified name from the specified assembly instance, and returns it as a dynamic object. See also <see cref="AsDynamicType"/>.
        /// </summary>
        /// <param name="assembly">The assembly instance to search for the type.</param>
        /// <param name="typeName">The type name.</param>
        /// <returns>The wrapped type.</returns>
        /// <seealso cref="AsDynamicType"/>
        public static dynamic GetDynamicType(this Assembly assembly, string typeName)
        {
            if (assembly is null)
                throw new ArgumentNullException(nameof(assembly));

            return assembly.GetType(typeName).AsDynamicType();
        }

        /// <summary>
        /// Tries to instantiate the type with the specified type name from the specified assembly instance using the specified constructor arguments.
        /// </summary>
        /// <param name="assembly">The assembly instance to search.</param>
        /// <param name="typeName">The full type name.</param>
        /// <param name="args">The arguments to pass to the constructor.</param>
        /// <returns></returns>
        /// <exception cref="MissingMethodException">Thrown when no suitable constructor can be found.</exception>
        public static dynamic CreateDynamicInstance(this Assembly assembly, string typeName, params object[] args)
        {
            if (args is null)
                throw new ArgumentNullException(nameof(args));

            return assembly.GetDynamicType(typeName).New(args);
        }
    }
}


================================================
FILE: src/ReflectionMagic/Property.cs
================================================
using System;
using System.Reflection;

namespace ReflectionMagic
{
    /// <summary>
    /// Provides an mechanism to access properties through the <see cref="IProperty"/> abstraction.
    /// </summary>
    internal class Property : IProperty
    {
        private readonly PropertyInfo _propertyInfo;

        /// <summary>
        /// Initializes a new instance of the <see cref="Property"/> class wrapping the specified property.
        /// </summary>
        /// <param name="property">The property info to wrap.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="property"/> is <c>null</c>.</exception>
        internal Property(PropertyInfo property)
        {
            _propertyInfo = property ?? throw new ArgumentNullException(nameof(property));
        }

        public Type PropertyType => _propertyInfo.PropertyType;

        string IProperty.Name => _propertyInfo.Name;

        object IProperty.GetValue(object obj, object[] index)
        {
            return _propertyInfo.GetValue(obj, index);
        }

        void IProperty.SetValue(object obj, object value, object[] index)
        {
            if (_propertyInfo.CanWrite)
            {
                _propertyInfo.SetValue(obj, value, index);
            }
            else
            {
                var backingFieldName = $"<{_propertyInfo.Name}>k__BackingField";
                for (var type = obj.GetType(); type != null; type = type.BaseType)
                {
                    var backingField = type.GetField(backingFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
                    if (backingField != null)
                    {
                        backingField.SetValue(obj, value);
                        return;
                    }
                }
                throw new MissingMemberException($"The property {obj.GetType()}.{_propertyInfo.Name} does not have a setter nor a backing field ({backingFieldName}).");
            }
        }
    }
}


================================================
FILE: src/ReflectionMagic/ReflectionMagic.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <VersionPrefix>5.0.1</VersionPrefix>
    <TargetFrameworks>net6.0;net462;netstandard2.0</TargetFrameworks>
    <NoWarn>$(NoWarn);CS1591</NoWarn>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <LangVersion>Latest</LangVersion>
    <DebugType>embedded</DebugType>
    <EmbedAllSources>true</EmbedAllSources>
  </PropertyGroup>

  <!-- Strong naming -->
  <PropertyGroup>
    <AssemblyOriginatorKeyFile>../../ReflectionMagic.snk</AssemblyOriginatorKeyFile>
    <SignAssembly>true</SignAssembly>
    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
  </PropertyGroup>

  <!-- NuGet properties -->
  <PropertyGroup>
    <PackageTags>dynamic</PackageTags>
    <PackageProjectUrl>https://github.com/davidebbo/ReflectionMagic</PackageProjectUrl>
    <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
    <PackageReadmeFile>README.md</PackageReadmeFile>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>

    <Description>Framework to drastically simplify your private reflection code using C# dynamic</Description>
    <Authors>David Ebbo</Authors>
    <Company>David Ebbo</Company>
    <Product>ReflectionMagic</Product>
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\..\README.md" Pack="true" PackagePath="" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
  </ItemGroup>

  <ItemGroup Condition="$(TargetFrameworkIdentifier) != '.NETCoreApp'">
    <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
  </ItemGroup>

</Project>


================================================
FILE: test/LibraryWithPrivateMembers/LibraryWithPrivateMembers.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net6.0;net462;netstandard2.0</TargetFrameworks>
    <IsPackable>false</IsPackable>
    <NoWarn>$(NoWarn);CS0169;CS0414</NoWarn>
  </PropertyGroup>

</Project>


================================================
FILE: test/LibraryWithPrivateMembers/MiscTestClasses.cs
================================================
using System;
using System.Collections.Generic;

namespace LibraryWithPrivateMembers
{
    // Only used as a covenient way to refer to this assembly
    public class MarkerType
    {
    }

    internal class FooBase
    {
        private int _somePrivateIntegerField = -1;

        private static int _somePrivateStaticIntegerField = 17;

        private int AddIntegers(int n1, int n2)
        {
            return n1 + n2;
        }


        private static double AddDoubles(double f1, double f2)
        {
            return f1 + f2;
        }

        internal string SomeMethodThatGetsHiddenInDerivedClass()
        {
            return "FooBase.SomeMethod";
        }

        internal string SomePropertyThatGetsHiddenInDerivedClass { get { return "FooBase.SomePropertyThatGetsHiddenInDerivedClass"; } }
    }

    internal class Foo : FooBase
    {
        public Foo()
        {
        }

        private Foo(int n)
        {
            SomeInternalInteger = n;
        }

        private Bar _bar = new Bar();
        private Bar _barNull;

        internal int SomeInternalInteger { get; set; }
        public bool SomePublicBool { get; set; }
        private string SomePrivateString { get; set; }

        private static string SomeFooStaticStringProperty { get; set; }

        private int AddIntegers(int n1, int n2, int n3)
        {
            return n1 + n2 + n3;
        }

        private string ReturnStringFromBarObject(Bar bar)
        {
            return bar.SomeBarStringProperty;
        }

        private string ReturnTypeName(Type t)
        {
            return t.FullName;
        }

        private object ReturnRefObject(ref object reffed)
        {
            return reffed;
        }

        private void AddTwoParametersWithOut(int a, int b, out int c)
        {
            c = a + b;
        }

        private void AddTwoRefParameters(ref int a, ref int b, ref int result)
        {
            result = a + b;
        }

        private Dictionary<string, string> _dict = new Dictionary<string, string>();
        internal string this[string s]
        {
            get
            {
                return _dict[s];
            }
            set
            {
                _dict[s] = value;
            }
        }

        private object SomeMethod(object obj)
        {
            return obj;
        }

        private T SomeGenericMethod<T>(T value)
        {
            return value;
        }

        private T2 SomeGenericMethod<T, T2>(T value, T2 value2)
        {
            return value2;
        }

        private Exception SomeMethodWithNoPrimitiveResult()
        {
            return new Exception();
        }

        internal new string SomeMethodThatGetsHiddenInDerivedClass()
        {
            return "Foo.SomeMethod";
        }

        internal new string SomePropertyThatGetsHiddenInDerivedClass { get { return "Foo.SomePropertyThatGetsHiddenInDerivedClass"; } }
    }

    internal class Bar
    {
        internal string SomeBarStringProperty { get; set; }
    }

    public class Baz
    {
        public int PublicGetOnlyInteger { get; }
        internal int InternalGetOnlyInteger { get; }
        private int PrivateGetOnlyInteger { get; }
    }

    public class Qux : Baz
    {
    }
}


================================================
FILE: test/ReflectionMagicTests/ConstructorSelectionTests.cs
================================================
using ReflectionMagic;
using Xunit;

namespace ReflectionMagicTests
{
    public class ConstructorSelectionTests
    {
        [Fact]
        public void CanFindNoArgsConstructor()
        {
            var type = typeof(TypeWithNoArgsConstructor).AsDynamicType();
            var instance = type.New();

            Assert.NotNull(instance);
        }

        [Fact]
        public void CanFindSingleArgumentIntConstructor()
        {
            var type = typeof(TypeWithSingleArgConstructor).AsDynamicType();
            var instance = type.New(1337);

            Assert.NotNull(instance);
            Assert.Equal(1337, instance.IntValue);
        }

        [Fact]
        public void CanFindSingleArgumentStringConstructor()
        {
            var type = typeof(TypeWithSingleArgConstructor).AsDynamicType();
            var instance = type.New("TestValue");

            Assert.NotNull(instance);
            Assert.Equal("TestValue", instance.StringValue);
        }

        [Fact]
        public void CanFindMultipleArgumentConstructor()
        {
            var type = typeof(TypeWithMultipleArgsConstructor).AsDynamicType();
            var instance = type.New(1337, "TestValue");

            Assert.NotNull(instance);
            Assert.Equal(1337, instance.IntValue);
            Assert.Equal("TestValue", instance.StringValue);
        }

        private class TypeWithNoArgsConstructor
        {
            public TypeWithNoArgsConstructor()
            {
            }
        }

        private class TypeWithSingleArgConstructor
        {
            public string StringValue { get; }

            public int IntValue { get; }

            public TypeWithSingleArgConstructor(int value)
            {
                IntValue = value;
            }

            public TypeWithSingleArgConstructor(string value)
            {
                StringValue = value;
            }
        }

        private class TypeWithMultipleArgsConstructor
        {
            public string StringValue { get; }

            public int IntValue { get; }

            public TypeWithMultipleArgsConstructor(int value, string stringValue)
            {
                IntValue = value;
                StringValue = stringValue;
            }
        }
    }
}


================================================
FILE: test/ReflectionMagicTests/ExtensionMethodFacts.cs
================================================
using ReflectionMagic;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace ReflectionMagicTests
{
    public class ExtensionMethodFacts
    {
        public class TheAsDynamicMethod
        {
            public static IEnumerable<object[]> PrimitiveValues = (new object[]
            {
                (int)1,
                (uint)1,
                (long)1,
                (byte)1,
                (double)1,
                (char)'a',
                (bool)true,
            }).Select(value => new object[] { value });

            [Fact]
            public void Should_WrapObjects()
            {
                var obj = new object();

                var wrapped = obj.AsDynamic();

                Assert.IsType<PrivateReflectionDynamicObjectInstance>(wrapped);
            }

            [Fact]
            public void Should_WrapStructs()
            {
                var @struct = new CustomStruct();

                var wrapped = @struct.AsDynamic();

                Assert.IsType<PrivateReflectionDynamicObjectInstance>(wrapped);
            }

            [Fact]
            public void Should_BeIdempotent()
            {
                var obj = new object();

                object wrapped = obj.AsDynamic();

                Assert.Equal(wrapped, wrapped.AsDynamic());
            }

            [Fact]
            public void Should_NotWrapNull()
            {
                object instance = null;

                Assert.Null(instance.AsDynamic());
            }

            [Fact]
            public void Should_NotWrapString()
            {
                string value = "Test value";

                object wrapped = value.AsDynamic();

                Assert.Same(value, wrapped);
            }

            [Theory]
            [MemberData(nameof(PrimitiveValues))]
            public void Should_NotWrapPrimitiveTypes(object primitive)
            {
                object wrapped = primitive.AsDynamic();

                Assert.Same(primitive, wrapped);
            }

            [Fact]
            public void Should_UnwrapObjects()
            {
                object obj = new object();
                dynamic wrapped = obj.AsDynamic();
                object unwrapped = DynamicHelper.Unwrap(wrapped);

                Assert.Same(unwrapped, obj);
            }

            [Fact]
            public void Should_UnwrapStructs()
            {
                var @struct = Guid.NewGuid();
                var wrapped = @struct.AsDynamic();
                object unwrapped = DynamicHelper.Unwrap(wrapped);

                Assert.Equal(unwrapped, @struct);
            }

            [Theory]
            [MemberData(nameof(PrimitiveValues))]
            public void Should_UnwrapPrimitiveTypes(object primitive)
            {
                dynamic wrapped = primitive.AsDynamic();
                object unwrapped = DynamicHelper.Unwrap(wrapped);

                Assert.Equal(unwrapped, primitive);
            }
        }
    }

    internal struct CustomStruct
    {

    }
}


================================================
FILE: test/ReflectionMagicTests/ReflectionMagicTests.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net6.0;net462</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\src\ReflectionMagic\ReflectionMagic.csproj" />
    <ProjectReference Include="..\LibraryWithPrivateMembers\LibraryWithPrivateMembers.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
    <PackageReference Include="xunit" Version="2.6.6" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

</Project>


================================================
FILE: test/ReflectionMagicTests/UnitTest.cs
================================================
using LibraryWithPrivateMembers;
using ReflectionMagic;
using System;
using System.Reflection;
using Xunit;

namespace ReflectionMagicTests
{
    public class UnitTest
    {
        private dynamic dynamicFooType;
        private dynamic dynamicFoo;

        public UnitTest()
        {
            dynamicFooType = typeof(MarkerType).Assembly.GetDynamicType("LibraryWithPrivateMembers.Foo");
            dynamicFoo = typeof(MarkerType).Assembly.CreateDynamicInstance("LibraryWithPrivateMembers.Foo");
        }

        [Fact]
        public void TestPropertyGetAndSetInternalInteger()
        {
            dynamicFoo.SomeInternalInteger = 17;
            Assert.Equal(17, dynamicFoo.SomeInternalInteger);
        }

        [Fact]
        public void TestPropertyGetAndSetPublicBool()
        {
            dynamicFoo.SomePublicBool = true;
            Assert.Equal(true, dynamicFoo.SomePublicBool);
        }

        [Fact]
        public void TestPropertyGetAndSetPrivateString()
        {
            dynamicFoo.SomePrivateString = "Hello";
            Assert.Equal("Hello", dynamicFoo.SomePrivateString);
        }

        [Fact]
        public void TestPrivateIntegerField()
        {
            Assert.Equal(-1, dynamicFoo._somePrivateIntegerField);
            dynamicFoo._somePrivateIntegerField = 12;
            Assert.Equal(12, dynamicFoo._somePrivateIntegerField);
        }

        [Fact]
        public void TestOperatorOnIntegers()
        {
            dynamicFoo.SomeInternalInteger = 17;
            Assert.Equal(35, dynamicFoo.SomeInternalInteger * 2 + 1);
        }

        [Fact]
        public void TestOperatorOnStrings()
        {
            dynamicFoo.SomePrivateString = "Hello";
            Assert.Equal("Hello world", dynamicFoo.SomePrivateString + " world");
            Assert.Equal("Say Hello", "Say " + dynamicFoo.SomePrivateString);
        }

        [Fact]
        public void TestMissingProperty()
        {
            Assert.Throws<MissingMemberException>(() => dynamicFoo.NotExist = "Hello");
        }

        [Fact]
        public void TestMissingMethod()
        {
            var exception = Assert.Throws<MissingMethodException>(() => dynamicFoo.NotExist());

            Assert.Contains("NotExist", exception.Message);
        }

        [Fact]
        public void FactCalls()
        {
            dynamicFoo.SomeInternalInteger = 17;

            // This one is defined on the base type
            var sum = dynamicFoo.AddIntegers(dynamicFoo.SomeInternalInteger, 3);
            Assert.Equal(20, sum);

            // Different overload defined on the type itself
            sum = dynamicFoo.AddIntegers(dynamicFoo.SomeInternalInteger, 3, 4);
            Assert.Equal(24, sum);
        }

        [Fact]
        public void TestCallToMethodThatHidesBaseMethod()
        {
            var val = dynamicFoo.SomeMethodThatGetsHiddenInDerivedClass();

            Assert.Equal("Foo.SomeMethod", val);
        }

        [Fact]
        public void TestCallToPropertyThatHidesBaseProperty()
        {
            var val = dynamicFoo.SomePropertyThatGetsHiddenInDerivedClass;

            Assert.Equal("Foo.SomePropertyThatGetsHiddenInDerivedClass", val);
        }

        [Fact]
        public void FactCallThatTakesObject()
        {
            dynamicFoo._bar.SomeBarStringProperty = "Blah1";
            var barString = dynamicFoo.ReturnStringFromBarObject(dynamicFoo._bar.RealObject);
            Assert.Equal("Blah1", barString);

            dynamicFoo._bar.SomeBarStringProperty = "Blah2";
            barString = dynamicFoo.ReturnStringFromBarObject(dynamicFoo._bar);
            Assert.Equal("Blah2", barString);
        }

        [Fact]
        public void FactCallThatTakesType()
        {
            var typeName = dynamicFoo.ReturnTypeName(dynamicFooType);
            Assert.Equal("LibraryWithPrivateMembers.Foo", typeName);
        }

        [Fact]
        public void TestPropertyGetAndSetOnSubObject()
        {
            dynamicFoo._bar.SomeBarStringProperty = "Blah";
            Assert.Equal("Blah", dynamicFoo._bar.SomeBarStringProperty);
        }

        [Fact]
        public void TestGettingBackRealObject()
        {
            object realBar = dynamicFoo._bar.RealObject;
            Assert.Equal("Bar", realBar.GetType().Name);
        }

        [Fact]
        public void TestObjectInstantiationWithNonDefaultCtor()
        {
            var foo = dynamicFooType.New(123);
            Assert.Equal(123, foo.SomeInternalInteger);
        }

        [Fact]
        public void TestStaticPropertyGetAndSet()
        {
            dynamicFooType.SomeFooStaticStringProperty = "zzz";
            Assert.Equal("zzz", dynamicFooType.SomeFooStaticStringProperty);
        }

        [Fact]
        public void TestStaticFieldGetAndSet()
        {
            Assert.Equal(17, dynamicFooType._somePrivateStaticIntegerField);
            dynamicFooType._somePrivateStaticIntegerField++;
            Assert.Equal(18, dynamicFooType._somePrivateStaticIntegerField);
        }

        [Fact]
        public void TestStaticMethodCall()
        {
            var sum = dynamicFooType.AddDoubles(2.5, 3.5);
            Assert.Equal(6, sum);
        }

        [Fact]
        public void TestNullSubObject()
        {
            Assert.Null(dynamicFoo._barNull);
        }

        [Fact]
        public void TestIndexedProperty()
        {
            dynamicFoo["Hello"] = "qqq";
            dynamicFoo["Hello2"] = "qqq2";
            Assert.Equal("qqq", dynamicFoo["Hello"]);
            Assert.Equal("qqq2", dynamicFoo["Hello2"]);
        }

        [Fact]
        public void TestDictionaryAccess()
        {
            dynamicFoo._dict["Hello"] = "qqq";
            dynamicFoo._dict["Hello2"] = "qqq2";
            Assert.Equal("qqq", dynamicFoo._dict["Hello"]);
            Assert.Equal("qqq2", dynamicFoo._dict["Hello2"]);
        }

        [Fact]
        public void TestGenericMethod()
        {
            var result = dynamicFoo.SomeGenericMethod<string>("test");
            Assert.Equal("test", result);
        }

        [Fact]
        public void TestGenericMethodWithTwoArguments()
        {
            var result = dynamicFoo.SomeGenericMethod<string, int>("test", 1234);
            Assert.Equal(1234, result);
        }

        [Fact]
        public void MethodWithNoPrimitiveResult()
        {
            var result = (Exception)dynamicFoo.SomeMethodWithNoPrimitiveResult();

            Assert.NotNull(result);
        }

        [Fact]
        public void NullToGenericMethod()
        {
            var result = dynamicFoo.SomeGenericMethod<string>(null);

            Assert.Null(result);
        }

        [Fact]
        public void TestNullToMethod()
        {
            var result = dynamicFoo.SomeMethod(null);

            Assert.Null(result);
        }

        [Fact]
        public void TestAddingByRef()
        {
            int a = 127;
            int b = 128;
            int c = 0;

            dynamicFoo.AddTwoRefParameters(ref a, ref b, ref c);

            Assert.Equal(255, c);
        }

        [Fact]
        public void TestAddingByOut()
        {
            int a = 127;
            int b = 110;

            dynamicFoo.AddTwoParametersWithOut(a, b, out int c);

            Assert.Equal(237, c);
        }

        [Fact]
        public void TestRefArgument()
        {
            object obj = "Test thingie";

            var returned = dynamicFoo.ReturnRefObject(ref obj);

            Assert.Equal(obj, returned);
        }

        [Fact]
        public void TestRefNullArgument()
        {
            object obj = null;

            var returned = dynamicFoo.ReturnRefObject(ref obj);

            Assert.Null(returned);
        }

        [Fact]
        public void TestPassNullToValueTypeRefParameter()
        {
            object first = null;
            int second = 2;
            int third = 0;

            Assert.Throws<MissingMethodException>(() => dynamicFoo.AddTwoRefParameters(ref first, ref second, ref third));
        }

        [Fact]
        public void TestSettingPublicGetOnlyProperty()
        {
            var baz = new Baz();
            baz.AsDynamic().PublicGetOnlyInteger = 42;

            Assert.Equal(42, baz.PublicGetOnlyInteger);
        }

        [Fact]
        public void TestSettingInternalGetOnlyProperty()
        {
            var baz = new Baz();
            baz.AsDynamic().InternalGetOnlyInteger = 42;

            Assert.Equal(42, baz.GetType().GetProperty("InternalGetOnlyInteger", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(baz));
        }

        [Fact]
        public void TestSettingPrivateGetOnlyProperty()
        {
            var baz = new Baz();
            baz.AsDynamic().PrivateGetOnlyInteger = 42;

            Assert.Equal(42, baz.GetType().GetProperty("PrivateGetOnlyInteger", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(baz));
        }

        [Fact]
        public void TestSettingPublicInheritedGetOnlyProperty()
        {
            var qux = new Qux();
            qux.AsDynamic().PublicGetOnlyInteger = 42;

            Assert.Equal(42, qux.PublicGetOnlyInteger);
        }

        [Fact]
        public void TestSettingInternalInheritedGetOnlyProperty()
        {
            var qux = new Qux();
            qux.AsDynamic().InternalGetOnlyInteger = 42;

            Assert.Equal(42, qux.GetType().BaseType?.GetProperty("InternalGetOnlyInteger", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(qux));
        }

        [Fact]
        public void TestSettingPrivateInheritedGetOnlyProperty()
        {
            var qux = new Qux();
            qux.AsDynamic().PrivateGetOnlyInteger = 42;

            Assert.Equal(42, qux.GetType().BaseType?.GetProperty("PrivateGetOnlyInteger", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(qux));
        }
    }
}
Download .txt
gitextract_3o09ty_o/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── README.md
├── ReflectionMagic.sln
├── ReflectionMagic.snk
├── build-nuget.cmd
├── build.ps1
├── src/
│   └── ReflectionMagic/
│       ├── DynamicHelper.cs
│       ├── Field.cs
│       ├── IProperty.cs
│       ├── PrivateReflectionDynamicObjectBase.cs
│       ├── PrivateReflectionDynamicObjectInstance.cs
│       ├── PrivateReflectionDynamicObjectStatic.cs
│       ├── PrivateReflectionUsingDynamicExtensions.cs
│       ├── Property.cs
│       └── ReflectionMagic.csproj
└── test/
    ├── LibraryWithPrivateMembers/
    │   ├── LibraryWithPrivateMembers.csproj
    │   └── MiscTestClasses.cs
    └── ReflectionMagicTests/
        ├── ConstructorSelectionTests.cs
        ├── ExtensionMethodFacts.cs
        ├── ReflectionMagicTests.csproj
        └── UnitTest.cs
Download .txt
SYMBOL INDEX (123 symbols across 12 files)

FILE: src/ReflectionMagic/DynamicHelper.cs
  class DynamicHelper (line 3) | public static class DynamicHelper
    method Unwrap (line 12) | public static object Unwrap(dynamic d)

FILE: src/ReflectionMagic/Field.cs
  class Field (line 9) | internal class Field : IProperty
    method Field (line 18) | internal Field(FieldInfo field)
    method GetValue (line 27) | object IProperty.GetValue(object obj, object[] index)
    method SetValue (line 32) | void IProperty.SetValue(object obj, object value, object[] index)

FILE: src/ReflectionMagic/IProperty.cs
  type IProperty (line 8) | public interface IProperty
    method GetValue (line 26) | object GetValue(object obj, object[] index);
    method SetValue (line 34) | void SetValue(object obj, object value, object[] index);

FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectBase.cs
  class PrivateReflectionDynamicObjectBase (line 10) | public abstract class PrivateReflectionDynamicObjectBase : DynamicObject
    method TryGetMember (line 23) | public override bool TryGetMember(GetMemberBinder binder, out object r...
    method TrySetMember (line 39) | public override bool TrySetMember(SetMemberBinder binder, object value)
    method TryGetIndex (line 52) | public override bool TryGetIndex(GetIndexBinder binder, object[] index...
    method TrySetIndex (line 66) | public override bool TrySetIndex(SetIndexBinder binder, object[] index...
    method TryInvokeMember (line 77) | public override bool TryInvokeMember(InvokeMemberBinder binder, object...
    method TryConvert (line 100) | public override bool TryConvert(ConvertBinder binder, out object result)
    method ToString (line 110) | public override string ToString()
    method GetIndexProperty (line 117) | private IProperty GetIndexProperty()
    method GetProperty (line 123) | private IProperty GetProperty(string propertyName)
    method GetTypeProperties (line 142) | private IDictionary<string, IProperty> GetTypeProperties(Type type)
    method ParametersCompatible (line 184) | private static bool ParametersCompatible(MethodInfo method, object[] p...
    method InvokeMethodOnType (line 250) | private static object InvokeMethodOnType(Type type, object target, str...
    method GetGenericMethodArguments (line 308) | private static Type[] GetGenericMethodArguments(InvokeMemberBinder bin...

FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectInstance.cs
  class PrivateReflectionDynamicObjectInstance (line 8) | public class PrivateReflectionDynamicObjectInstance : PrivateReflectionD...
    method PrivateReflectionDynamicObjectInstance (line 19) | public PrivateReflectionDynamicObjectInstance(object instance)

FILE: src/ReflectionMagic/PrivateReflectionDynamicObjectStatic.cs
  class PrivateReflectionDynamicObjectStatic (line 9) | public class PrivateReflectionDynamicObjectStatic : PrivateReflectionDyn...
    method PrivateReflectionDynamicObjectStatic (line 18) | public PrivateReflectionDynamicObjectStatic(Type type)
    method New (line 37) | public dynamic New(params object[] args)

FILE: src/ReflectionMagic/PrivateReflectionUsingDynamicExtensions.cs
  class PrivateReflectionUsingDynamicExtensions (line 6) | public static class PrivateReflectionUsingDynamicExtensions
    method AsDynamic (line 17) | public static dynamic AsDynamic(this object o)
    method AsDynamicType (line 32) | public static dynamic AsDynamicType(this Type type)
    method GetDynamicType (line 44) | public static dynamic GetDynamicType(this Assembly assembly, string ty...
    method CreateDynamicInstance (line 60) | public static dynamic CreateDynamicInstance(this Assembly assembly, st...

FILE: src/ReflectionMagic/Property.cs
  class Property (line 9) | internal class Property : IProperty
    method Property (line 18) | internal Property(PropertyInfo property)
    method GetValue (line 27) | object IProperty.GetValue(object obj, object[] index)
    method SetValue (line 32) | void IProperty.SetValue(object obj, object value, object[] index)

FILE: test/LibraryWithPrivateMembers/MiscTestClasses.cs
  class MarkerType (line 7) | public class MarkerType
  class FooBase (line 11) | internal class FooBase
    method AddIntegers (line 17) | private int AddIntegers(int n1, int n2)
    method AddDoubles (line 23) | private static double AddDoubles(double f1, double f2)
    method SomeMethodThatGetsHiddenInDerivedClass (line 28) | internal string SomeMethodThatGetsHiddenInDerivedClass()
  class Foo (line 36) | internal class Foo : FooBase
    method Foo (line 38) | public Foo()
    method Foo (line 42) | private Foo(int n)
    method AddIntegers (line 56) | private int AddIntegers(int n1, int n2, int n3)
    method ReturnStringFromBarObject (line 61) | private string ReturnStringFromBarObject(Bar bar)
    method ReturnTypeName (line 66) | private string ReturnTypeName(Type t)
    method ReturnRefObject (line 71) | private object ReturnRefObject(ref object reffed)
    method AddTwoParametersWithOut (line 76) | private void AddTwoParametersWithOut(int a, int b, out int c)
    method AddTwoRefParameters (line 81) | private void AddTwoRefParameters(ref int a, ref int b, ref int result)
    method SomeMethod (line 99) | private object SomeMethod(object obj)
    method SomeGenericMethod (line 104) | private T SomeGenericMethod<T>(T value)
    method SomeGenericMethod (line 109) | private T2 SomeGenericMethod<T, T2>(T value, T2 value2)
    method SomeMethodWithNoPrimitiveResult (line 114) | private Exception SomeMethodWithNoPrimitiveResult()
    method SomeMethodThatGetsHiddenInDerivedClass (line 119) | internal new string SomeMethodThatGetsHiddenInDerivedClass()
  class Bar (line 127) | internal class Bar
  class Baz (line 132) | public class Baz
  class Qux (line 139) | public class Qux : Baz

FILE: test/ReflectionMagicTests/ConstructorSelectionTests.cs
  class ConstructorSelectionTests (line 6) | public class ConstructorSelectionTests
    method CanFindNoArgsConstructor (line 8) | [Fact]
    method CanFindSingleArgumentIntConstructor (line 17) | [Fact]
    method CanFindSingleArgumentStringConstructor (line 27) | [Fact]
    method CanFindMultipleArgumentConstructor (line 37) | [Fact]
    class TypeWithNoArgsConstructor (line 48) | private class TypeWithNoArgsConstructor
      method TypeWithNoArgsConstructor (line 50) | public TypeWithNoArgsConstructor()
    class TypeWithSingleArgConstructor (line 55) | private class TypeWithSingleArgConstructor
      method TypeWithSingleArgConstructor (line 61) | public TypeWithSingleArgConstructor(int value)
      method TypeWithSingleArgConstructor (line 66) | public TypeWithSingleArgConstructor(string value)
    class TypeWithMultipleArgsConstructor (line 72) | private class TypeWithMultipleArgsConstructor
      method TypeWithMultipleArgsConstructor (line 78) | public TypeWithMultipleArgsConstructor(int value, string stringValue)

FILE: test/ReflectionMagicTests/ExtensionMethodFacts.cs
  class ExtensionMethodFacts (line 9) | public class ExtensionMethodFacts
    class TheAsDynamicMethod (line 11) | public class TheAsDynamicMethod
      method Should_WrapObjects (line 24) | [Fact]
      method Should_WrapStructs (line 34) | [Fact]
      method Should_BeIdempotent (line 44) | [Fact]
      method Should_NotWrapNull (line 54) | [Fact]
      method Should_NotWrapString (line 62) | [Fact]
      method Should_NotWrapPrimitiveTypes (line 72) | [Theory]
      method Should_UnwrapObjects (line 81) | [Fact]
      method Should_UnwrapStructs (line 91) | [Fact]
      method Should_UnwrapPrimitiveTypes (line 101) | [Theory]
  type CustomStruct (line 113) | internal struct CustomStruct

FILE: test/ReflectionMagicTests/UnitTest.cs
  class UnitTest (line 9) | public class UnitTest
    method UnitTest (line 14) | public UnitTest()
    method TestPropertyGetAndSetInternalInteger (line 20) | [Fact]
    method TestPropertyGetAndSetPublicBool (line 27) | [Fact]
    method TestPropertyGetAndSetPrivateString (line 34) | [Fact]
    method TestPrivateIntegerField (line 41) | [Fact]
    method TestOperatorOnIntegers (line 49) | [Fact]
    method TestOperatorOnStrings (line 56) | [Fact]
    method TestMissingProperty (line 64) | [Fact]
    method TestMissingMethod (line 70) | [Fact]
    method FactCalls (line 78) | [Fact]
    method TestCallToMethodThatHidesBaseMethod (line 92) | [Fact]
    method TestCallToPropertyThatHidesBaseProperty (line 100) | [Fact]
    method FactCallThatTakesObject (line 108) | [Fact]
    method FactCallThatTakesType (line 120) | [Fact]
    method TestPropertyGetAndSetOnSubObject (line 127) | [Fact]
    method TestGettingBackRealObject (line 134) | [Fact]
    method TestObjectInstantiationWithNonDefaultCtor (line 141) | [Fact]
    method TestStaticPropertyGetAndSet (line 148) | [Fact]
    method TestStaticFieldGetAndSet (line 155) | [Fact]
    method TestStaticMethodCall (line 163) | [Fact]
    method TestNullSubObject (line 170) | [Fact]
    method TestIndexedProperty (line 176) | [Fact]
    method TestDictionaryAccess (line 185) | [Fact]
    method TestGenericMethod (line 194) | [Fact]
    method TestGenericMethodWithTwoArguments (line 201) | [Fact]
    method MethodWithNoPrimitiveResult (line 208) | [Fact]
    method NullToGenericMethod (line 216) | [Fact]
    method TestNullToMethod (line 224) | [Fact]
    method TestAddingByRef (line 232) | [Fact]
    method TestAddingByOut (line 244) | [Fact]
    method TestRefArgument (line 255) | [Fact]
    method TestRefNullArgument (line 265) | [Fact]
    method TestPassNullToValueTypeRefParameter (line 275) | [Fact]
    method TestSettingPublicGetOnlyProperty (line 285) | [Fact]
    method TestSettingInternalGetOnlyProperty (line 294) | [Fact]
    method TestSettingPrivateGetOnlyProperty (line 303) | [Fact]
    method TestSettingPublicInheritedGetOnlyProperty (line 312) | [Fact]
    method TestSettingInternalInheritedGetOnlyProperty (line 321) | [Fact]
    method TestSettingPrivateInheritedGetOnlyProperty (line 330) | [Fact]
Condensed preview — 25 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (67K chars).
[
  {
    "path": ".config/dotnet-tools.json",
    "chars": 177,
    "preview": "{\n  \"version\": 1,\n  \"isRoot\": true,\n  \"tools\": {\n    \"dotnet-validate\": {\n      \"version\": \"0.0.1-preview.304\",\n      \"c"
  },
  {
    "path": ".editorconfig",
    "chars": 286,
    "preview": "# editorconfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Default settings:\n# A newline ending every file\n# Use 4 "
  },
  {
    "path": ".gitattributes",
    "chars": 184,
    "preview": "# \n*    text=auto\n*.cs diff=csharp\n\n# Solutions and projects should use windows line endings\n*.sln    text eol=crlf\n*.cs"
  },
  {
    "path": ".gitignore",
    "chars": 101,
    "preview": "bin\nobj\nPackages\nTestResults\n*.csproj.user\n*.vsp\n*.psess\n*.suo\n*.nupkg\n*.user\n\n.vs\n\nproject.lock.json"
  },
  {
    "path": "LICENSE.txt",
    "chars": 10201,
    "preview": " \n                                 Apache License\n                           Version 2.0, January 2004\n                 "
  },
  {
    "path": "README.md",
    "chars": 2546,
    "preview": "# ReflectionMagic\n[![Build Status](https://dev.azure.com/jvandertil/OpenSource/_apis/build/status/github/ReflectionMagic"
  },
  {
    "path": "ReflectionMagic.sln",
    "chars": 2966,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.26228.4\r\n"
  },
  {
    "path": "build-nuget.cmd",
    "chars": 451,
    "preview": "@echo off\nIF \"%Configuration%\"==\"\" (SET Configuration=Release)\nIF \"%Configuration%\"==\"Release\" (SET ContinuousIntegratio"
  },
  {
    "path": "build.ps1",
    "chars": 1569,
    "preview": "param (\n    [string]$OutputDirectory = $PSScriptRoot,\n    [string]$TestResultOutputDirectory = (Join-Path $PSScriptRoot "
  },
  {
    "path": "src/ReflectionMagic/DynamicHelper.cs",
    "chars": 762,
    "preview": "namespace ReflectionMagic\n{\n    public static class DynamicHelper\n    {\n        /// <summary>\n        /// Unwraps the sp"
  },
  {
    "path": "src/ReflectionMagic/Field.cs",
    "chars": 1148,
    "preview": "using System;\nusing System.Reflection;\n\nnamespace ReflectionMagic\n{\n    /// <summary>\n    /// Provides a mechanism to a"
  },
  {
    "path": "src/ReflectionMagic/IProperty.cs",
    "chars": 1545,
    "preview": "using System;\n\nnamespace ReflectionMagic\n{\n    /// <summary>\n    /// Defines an mechanism to access members (e.g. fields"
  },
  {
    "path": "src/ReflectionMagic/PrivateReflectionDynamicObjectBase.cs",
    "chars": 11648,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Dynamic;\nusing System.Linq;\nusing"
  },
  {
    "path": "src/ReflectionMagic/PrivateReflectionDynamicObjectInstance.cs",
    "chars": 1580,
    "preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace"
  },
  {
    "path": "src/ReflectionMagic/PrivateReflectionDynamicObjectStatic.cs",
    "chars": 1888,
    "preview": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing Sys"
  },
  {
    "path": "src/ReflectionMagic/PrivateReflectionUsingDynamicExtensions.cs",
    "chars": 3090,
    "preview": "using System;\nusing System.Reflection;\n\nnamespace ReflectionMagic\n{\n    public static class PrivateReflectionUsingDynami"
  },
  {
    "path": "src/ReflectionMagic/Property.cs",
    "chars": 2010,
    "preview": "using System;\nusing System.Reflection;\n\nnamespace ReflectionMagic\n{\n    /// <summary>\n    /// Provides an mechanism to a"
  },
  {
    "path": "src/ReflectionMagic/ReflectionMagic.csproj",
    "chars": 1688,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <VersionPrefix>5.0.1</VersionPrefix>\r\n    <TargetFrameworks"
  },
  {
    "path": "test/LibraryWithPrivateMembers/LibraryWithPrivateMembers.csproj",
    "chars": 244,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFrameworks>net6.0;net462;netstandard2.0</TargetFrame"
  },
  {
    "path": "test/LibraryWithPrivateMembers/MiscTestClasses.cs",
    "chars": 3279,
    "preview": "using System;\nusing System.Collections.Generic;\n\nnamespace LibraryWithPrivateMembers\n{\n    // Only used as a covenient "
  },
  {
    "path": "test/ReflectionMagicTests/ConstructorSelectionTests.cs",
    "chars": 2277,
    "preview": "using ReflectionMagic;\nusing Xunit;\n\nnamespace ReflectionMagicTests\n{\n    public class ConstructorSelectionTests\n    {\n"
  },
  {
    "path": "test/ReflectionMagicTests/ExtensionMethodFacts.cs",
    "chars": 3069,
    "preview": "using ReflectionMagic;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\n\nnamespace Refle"
  },
  {
    "path": "test/ReflectionMagicTests/ReflectionMagicTests.csproj",
    "chars": 776,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFrameworks>net6.0;net462</TargetFrameworks>\r\n  </Pro"
  },
  {
    "path": "test/ReflectionMagicTests/UnitTest.cs",
    "chars": 9925,
    "preview": "using LibraryWithPrivateMembers;\nusing ReflectionMagic;\nusing System;\nusing System.Reflection;\nusing Xunit;\n\nnamespace R"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the ReflectionMagic/ReflectionMagic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 25 files (61.9 KB), approximately 14.1k tokens, and a symbol index with 123 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!