vendredi 10 août 2018

Alternative to reflection for accessing private members via compiling against a modified assembly with public members

Summary

I searched for an alternative for accessing private members with reflection and it seems I found one.
The remaining questions are:

  1. Does it always work, regardless of the environment?
  2. Are there any reasons not to use it?

Reasons for the search of an alternative

Using reflection or some reflection tools which simplify it a bit come at the price of an overhead both in regard of programming work and computational resources. Especially if you need to work with instances of a private type it gets really cumbersome.
Also you loose the benefits of code completion and other features of your IDE. Even simple typos can result in errors, because you use strings for reflection.

The alternative method

Take the original assembly and change the private/non-public members to public (via an IL-Editor, a decompiler or Cecil).
Add this modified assembly to your references, then you can develop with ease, because the compiler thinks you can access them (which you can for this version of it).
Yet if you use your compiled assembly against the original assembly this only works for types, because if you access other private members you get during runtime an access violation exception.
Except if you enable "Allow unsafe code", then it seems to not care about access modifiers anymore.
I didn't find any information about this feature(?), but this option and the related unsafe keyword within code is normally primarily for pointers.

For me it's working, but I don't know if this behavior is consistent in other cases like different operating systems and CLR versions.
Also if there are any other reasons why not to use this technique.

Assembly Publicizer

I've wrote a tool to create a copy of an assembly in which all members are public (types, methods, fields, getters and setters of properties).

https://github.com/CabbageCrow/AssemblyPublicizer

It's simple to use, on windows you can even drag and drop your assembly on the exe.

Potential workflow

  1. Publicize the original assembly (with the tool)
  2. Use the publicized assembly as a reference
  3. Develop without any hassle of reflection to access private members and be happy about that
  4. Compile with "Allow unsafe code" enabled
    See https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/unsafe-compiler-option
  5. Use your own assembly with the original unmodified assembly which still can magically access private members.




Aucun commentaire:

Enregistrer un commentaire