Public library names are a compatibility contract
A consumer compiled against InvoiceCalculator.Calculate must still resolve that type and method. For a class library, FreeObfuscator disables public renaming and targets eligible private and internal symbols instead. Compatibility exclusions may leave some implementation names unchanged.
This preserves the naming contract; it does not prove every runtime path works. Reflection, serialization, resources, signing and dependencies need application-specific checks.
Measured DLL case: compare the contract, then run the caller
We processed a self-authored .NET 8 invoice library through the production anonymous Free endpoint. The public API includes an interface, a calculator, invoice properties and an event. It is an unsigned demonstration library, not a customer SDK.
In addition to the C# calculation example, we compared the exported types, declared public members and assembly identity of the original and protected DLLs:
| Check | Observed result |
|---|---|
| Exported public types | 3, unchanged |
| Public-contract entries | 24, identical; includes types, constructors, methods, properties, event and accessors |
| Assembly identity | InvoiceLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null; unchanged |
| Compiled consumer | Same consumer binary; no recompilation |
| Runtime comparison | 10 explicit checks pass; original and protected output match |
| Private implementation | ILSpy shows _calculationCount → @b and RoundMoney → @d |
The 24 entries are a reflection snapshot, not 24 independent behavior tests: getter/setter and event-accessor methods appear alongside their properties and event. The ten consumer checks cover five expected totals, JSON fields and round trip, events, state and an invalid-quantity exception.
Download the DLL contract case Read all 24 contract entries
The ZIP contains source, original/protected library folders, the unchanged consumer, ILSpy listings, runtime results and a contract-comparison script. Its hashes identify the captured files. A preserved signature list and one consumer do not certify every consumer, framework or publish mode.
Reproduce the DLL checks
- Extract the sample and review its source and README.
- Run
dotnet original/InvoiceConsumer.dll, thendotnet protected/InvoiceConsumer.dll. Both assert ten checks and print the same invoice JSON. - Run the included public-API comparison script to reproduce the signature and assembly-identity comparison.
- Open both
InvoiceLibrary.dllfiles in ILSpy. PublicCalculateremains, while the private field and rounding helper have short names.
For your own library, compile a consumer against the original once, replace only the library in a separate staging folder under its expected filename, and run the unchanged consumer. Recompiling the caller against the protected DLL can hide a compatibility break.
DLL extension does not mean class library
A modern .NET application may also be a DLL, with a managed entry point. That application can opt into public renaming; a class library cannot. See the application DLL and Windows launcher case for the opposite boundary. A native C/C++ DLL is not a supported managed input.
Even a private library can have other assemblies compiled against its public names. This service keeps class-library public names; requesting public renaming does not override that safeguard.
What else to test before distributing a DLL
- Reflection and wire formats: exercise string-based lookups, serializers, DI conventions and resources. Explicit JSON names work in this sample; that does not cover every serializer.
- Nested APIs and callbacks: verify public nested types, generic callers, interface dispatch, events and plugins actually used by your consumers.
- Signing and packaging: this sample is unsigned and is not a NuGet-package validation. Independently verify strong names, package layout, assembly loading and supported target frameworks.
- Release behavior: exercise normal and exceptional paths with the real dependency versions and configuration. A successful load alone is insufficient.
Frequently asked about DLL obfuscation
Will existing callers still use my obfuscated DLL?
Public class-library APIs are preserved, but test the actual callers. The measured unsigned .NET 8 sample keeps 24 contract entries and passes ten runtime checks with the same compiled consumer.
Does every DLL count as a library?
No. An application DLL can have a managed entry point. The extension is not the deciding factor, and public renaming remains disabled for class libraries.
Can I obfuscate a native DLL?
No. This tool expects a managed .NET assembly, not a native C/C++ binary.
Free supports one managed file up to 1 MB, with no account. It renames eligible symbols; strings and algorithms can remain readable. Pro adds deeper transforms and larger-file workflows. Compare the verification evidence, compatibility guide and .NET overview before choosing your settings.