#
Reflection Problems
#
Why renaming obfuscation breaks code that uses reflection
When you turn on the Obfuscation option, every type, method, property, field, event, parameter, and namespace can be renamed to meaningless identifiers. While this thwarts casual IL inspection, it introduces runtime failures anywhere your program expects the original metadata names to exist.
Typical patterns that fail are:
In short, any string-based reference to metadata breaks once those identifiers are no longer the same.
⚠️ .NET Reactor detects fully-qualified type names and rewrite those literals to the new obfuscated names automatically. If you always pass the full name (e.g., "MyApp.Services.EmailService, MyApp"), Type.GetType will still succeed after obfuscation. This auto-fixing does not help with partial names, member names, or values that are built at run time, so the guidelines below remain essential.
#
Fixing it with System.Reflection.ObfuscationAttribute
.NET
ships an attribute that .NET Reactor understand: System.Reflection.ObfuscationAttribute
.
You decorate exactly the types or members that must stay intact.
#
Common attribute properties
#
At the class level – exclude a whole type (and its members)
using System.Reflection;
namespace MyApp.Services
{
[Obfuscation(ApplyToMembers = true)]
internal class EmailService
{
public void SendEmail(string to, string subject) { … }
}
}
EmailService
and everything inside it remain exactly as compiled (EmailService
, SendEmail
, subject
, …).
#
At the method or property level – fine-grained control
internal class ReportBuilder
{
// Only this method keeps its name; the rest of the class can be renamed.
[Obfuscation()]
public string BuildFromTemplate(string templateName) { … }
}
#
Practical checklist
- Audit reflection usage — Search for
.GetType(..)
,Activator.CreateInstance(..)
,GetMethod(..)
,nameof(..)
,[Route(..)]
, resource look-ups, XAML bindings, etc. - Categorize — Decide whether to allow renaming and patch code (e.g., use
typeof(T)
instead of strings) or keep original names. - Annotate — Add
ObfuscationAttribute
where keeping names is simpler than refactoring. - Automated test pass — Run integration tests against the obfuscated build—reflection issues often surface immediately as
TypeLoadException
or binding errors.
By explicitly marking only the reflection-critical hotspots with ObfuscationAttribute
, you get the best of both worlds: robust runtime behavior and maximum symbol scrambling everywhere else.
See also: Advanced Rules Editor, Declarative Protection