another-guy - Mirror 1.0.2-b00023

Syntax-honeyed .NET reflection

PM> Install-Package Mirror -Version 1.0.2-b00023 -Source https://www.myget.org/F/another-guy/api/v3/index.json

Copy to clipboard

> nuget.exe install Mirror -Version 1.0.2-b00023 -Source https://www.myget.org/F/another-guy/api/v3/index.json

Copy to clipboard

> dotnet add package Mirror --version 1.0.2-b00023 --source https://www.myget.org/F/another-guy/api/v3/index.json

Copy to clipboard
<PackageReference Include="Mirror" Version="1.0.2-b00023" />
Copy to clipboard
source https://www.myget.org/F/another-guy/api/v3/index.json

nuget Mirror  ~> 1.0.2-b00023
Copy to clipboard

> choco install Mirror --version 1.0.2-b00023 --source https://www.myget.org/F/another-guy/api/v2

Copy to clipboard
Import-Module PowerShellGet
Register-PSRepository -Name "another-guy" -SourceLocation "https://www.myget.org/F/another-guy/api/v2"
Install-Module -Name "Mirror" -RequiredVersion "1.0.2-b00023" -Repository "another-guy" -AllowPreRelease
Copy to clipboard

Synopsis

Mirror

Simplifies C# reflection code.

Status

NuGet (stable)

NuGet NuGet

MyGet (latest)

MyGet CI MyGet CI

Build

Build status

Issues and pull requests

GitHub issues

Code Example

Describing the target

To access or invoke a private method that is defined on a type or an object client code needs to specify the target correctly. Targets' members can be either static or instance. Notice that constructors must be accessed through a static target since no instance target is available yet:

class MyClass {
  private string name;
  private MyClass() { this.name = "Name is not set"; }
  private MyClass(string name) { this.name = name; }
}

MyClass targetObject = ...;

var staticTarget = Use.Target<MyClass>();
// staticTarget can now be used to call constructor or
// call or access static members

var instanceTarget = Use.Target(targetObject)
// instanceTarget can now be used to call or access targetObject's members

Creating an instance of an object

// Creates object by calling its default constructor
MyClass newInstance = Use.Target<MyClass>().ToCreateInstance();

// Creates object by calling its best matching parameterized constructor
MyClass newInstance = Use.Target<MyClass>().ToCreateInstance("Alice");

Working with instance members

class MyClass {
  private string name;
  private string Name { get { return name; } set { name = value } }
  private void SetName(string newName) { name = newName; }
  private string GetName() { return name; }
}
MyClass target = new MyClass();

// Field/Property access code looks similar
Use.Target(target).Set("name").Value("Bob")
Use.Target(target).Set("Name").Value("Chris")
string nameFromField = Use.Target(target).ToGet<string>("name");
string nameFromProperty = Use.Target(target).ToGet<string>("Name");

// Method access
Use.Target(target).ToCall("SetName", "David");
string nameFromMethod = Use.Target(target).ToCall<string>("GetName");

Working with static members

static class MyClass {
  private static string name;
  private static string Name { get { return name; } set { name = value } }
  private static void SetName(string newName) { name = newName; }
  private static string GetName() { return name; }
}

Use.Target<MyClass>().Set("name").Value("Bob")
string nameFromStaticField = Use.Target<MyClass>().ToGet<string>("name");

Use.Target<MyClass>().Set("Name").Value("Chris")
string nameFromStaticProperty = Use.Target<MyClass>().ToGet<string>("Name");

Use.Target<MyClass>().ToCall("SetName", "David");
string nameFromStaticMethod = Use.Target<MyClass>().ToCall<string>("GetName");

Attribute discovery

Attribute retrieval can be string-based (full type name argument required).

IEnumerable<Attribute> obsoleteClassAttribute =
	typeof(TargetClass)
		.GetAttributes("System.Obsolete")
		.SingleOrDefault();

IEnumerable<Attribute> obsoleteMethodAttribute =
	typeof(TargetClass)
		.GetMethod("TargetMethod")
		.GetAttributes("System.Obsolete")
		.SingleOrDefault();

Alternatively, the generic method can be used if specific attribute type is known at compile time.

IEnumerable<Obsolete> obsoleteClassAttribute =
	typeof(TargetClass)
		.GetAttributes<Obsolete>()
		.SingleOrDefault();

IEnumerable<Obsolete> obsoleteMethodAttribute =
	typeof(TargetClass)
		.GetMethod("TargetMethod")
		.GetAttributes<Obsolete>()
		.SingleOrDefault();

Motivation

Syntax sugar is syntax sugar: it's not a necessary thing per se but it can improve code quality. Reflection should be your last resort tool when used in production code: types very often limit constructor and other members' accessibility level on purpose.

In your tests, however, it may be okay to have slightly sloppier code. For example, you may want to build a dummy/fake object and for some reason mocking tools like NSubstitute can't do it.

Installation

Mirror is a available in a form of a NuGet package. Follow regular installation process to bring it to your project. https://www.nuget.org/packages/Mirror/

Tests

Unit tests are available in Mirror.Tests project.

License

The code is distributed under the MIT license.

Reporting an Issue

Reporting an issue, proposing a feature, or asking a question are all great ways to improve software quality.

Here are a few important things that package contributors will expect to see in a new born GitHub issue:

  • the relevant version of the package;
  • the steps to reproduce;
  • the expected result;
  • the observed result;
  • some code samples illustrating current inconveniences and/or proposed improvements.

Contributing

Contribution is the best way to improve any project!

  1. Fork it!
  2. Create your feature branch (git checkout -b my-new-feature).
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

...or follow steps described in a nice fork guide by Karl Broman

  • .NETCoreApp 1.0
    • Microsoft.NETCore.App (>= 1.0.0)
    • NETStandard.Library (>= 1.6.0)
  • .NETCoreApp 1.0: 1.0.0.0

Owners

another-guy

Authors

Igor Soloydenko

Project URL

https://github.com/another-guy/Mirror

License

MIT

Tags

Reflection,Syntax,Sugar

Info

60 total downloads
2 downloads for version 1.0.2-b00023
Download (6.38 KB)
Found on the current feed only

Package history

Version Size Last updated Downloads Mirrored?
2.1.0 6.76 KB Fri, 06 Jan 2017 16:29:30 GMT 2
2.1.0-b00040 6.77 KB Fri, 16 Jun 2017 17:40:46 GMT 2
2.1.0-b00039 6.77 KB Fri, 06 Jan 2017 19:12:39 GMT 2
2.1.0-b00038 6.77 KB Fri, 06 Jan 2017 19:11:15 GMT 2
2.1.0-b00037 6.77 KB Fri, 06 Jan 2017 19:07:20 GMT 3
2.1.0-b00036 6.77 KB Fri, 06 Jan 2017 19:06:06 GMT 2
2.1.0-b00034 6.77 KB Fri, 06 Jan 2017 16:27:57 GMT 2
2.0.0 6.69 KB Fri, 06 Jan 2017 01:29:50 GMT 2
2.0.0-b00033 6.72 KB Fri, 06 Jan 2017 01:35:01 GMT 3
2.0.0-b00031 6.7 KB Fri, 06 Jan 2017 01:26:42 GMT 2
2.0.0-b00030 6.38 KB Thu, 05 Jan 2017 16:25:59 GMT 1
1.0.3-b00029 6.39 KB Sun, 28 Aug 2016 04:22:00 GMT 4
1.0.3-b00028 6.39 KB Sun, 28 Aug 2016 04:20:53 GMT 3
1.0.3-b00027 6.39 KB Sun, 07 Aug 2016 22:28:13 GMT 2
1.0.3-b00026 6.39 KB Sun, 07 Aug 2016 22:18:06 GMT 3
1.0.3-b00025 6.38 KB Sat, 06 Aug 2016 00:35:04 GMT 1
1.0.3-b00024 6.39 KB Sat, 06 Aug 2016 00:08:57 GMT 4
1.0.2 6.38 KB Fri, 05 Aug 2016 06:05:55 GMT 3
1.0.2-b00023 6.38 KB Fri, 05 Aug 2016 23:46:41 GMT 2
1.0.2-b00021 6.38 KB Fri, 05 Aug 2016 06:04:17 GMT 4
1.0.1-b00020 6.38 KB Fri, 05 Aug 2016 04:33:19 GMT 2
1.0.1-b00019 6.38 KB Thu, 04 Aug 2016 15:10:29 GMT 2
1.0.1-b00018 6.38 KB Thu, 04 Aug 2016 06:36:16 GMT 4
1.0.1-b00017 6.38 KB Thu, 04 Aug 2016 06:34:59 GMT 3