# Trimming Problems

Trimming and .NET Reactor can be used together, but the required configuration depends on the order in which trimming and protection are applied.

There are two separate concerns:

  • If trimming runs before protection, the trimmer must keep the classes, members, and references that the code injected later by .NET Reactor will require.
  • If trimming runs after protection, the trimmer modifies an already protected assembly. Some protection features rely on metadata or other values remaining unchanged and are therefore not compatible with this build order.

# Solution

Choose the configuration that matches your build order:

  • Trim first, then protect: Use Eziriz.Reactor.TrimHelper so the trimmer preserves everything required by the protection code. No .NET Reactor protection feature needs to be disabled.
  • Protect first, then trim: Some protection features must be disabled because trimming modifies the protected assembly. Depending on the project and build type, Eziriz.Reactor.TrimHelper may still be required. If trimming or the resulting application does not work correctly, add the helper as described below.

# 1. Install the NuGet Package

Eziriz.Reactor.TrimHelper is required when trimming runs before .NET Reactor protection. It ensures that the trimmer keeps the classes, members, and references that may later be required by the injected protection code.

When protection runs before trimming, the helper is not always necessary, but it can still be required depending on the project and build type. If you encounter trimming or runtime problems, use the helper and the configuration below.

dotnet add package Eziriz.Reactor.TrimHelper

Alternatively, you can install it via the NuGet Package Manager in your IDE.

NuGet Package Link:
Eziriz.Reactor.TrimHelper


# 2. Update the Project File

When using Eziriz.Reactor.TrimHelper, add the following configuration to your project file (.csproj, .vbproj, etc.) to explicitly preserve all types and members in the TrimHelper assembly:

<ItemGroup>
  <TrimmerRootAssembly Include="TrimHelper" RootMode="library" />
</ItemGroup>

Read more: Root Assemblies


# 3. Alternatively Use a Link XML File

Instead of using TrimmerRootAssembly, you can use a link.xml file.

Create a file named link.xml with the following content and replace YourAssembly with the name of your own assembly:

<linker>
  <assembly fullname="TrimHelper">
    <type fullname="*" preserve="all" />
  </assembly>
  <assembly fullname="YourAssembly">
    <type fullname="*" preserve="all" />
  </assembly>
</linker>

The <linker> root element is required. This example also preserves every type and member in YourAssembly. Narrow that part only after verifying which application code must remain available.

Read more: ILLink descriptor format

Then add the following entry to your project file:

<ItemGroup>
  <TrimmerRootDescriptor Include="link.xml" />
</ItemGroup>

# 4. Protection Order and Feature Restrictions

# Trimming before protection

If trimming is completed before .NET Reactor protects the application, use Eziriz.Reactor.TrimHelper as described above. This ensures that the assembly still contains the references required by the code that .NET Reactor injects later.

The major advantage of this build order is that the protected assembly is not modified afterwards.

Therefore no protection feature needs to be disabled.

# Trimming after protection

With the Visual Studio / Rider Add-in or Build Integration Manager, selecting After Compile applies protection before trimming.

In this order, the trimmer modifies an assembly that has already been protected. Some protection features expect metadata or other values in the protected assembly to remain unchanged and should therefore not be enabled.

Disable Anti ILDASM / Suppress Decompilation for trimming
Disable Anti ILDASM / Suppress Decompilation for trimming

Depending on the project and build type, Eziriz.Reactor.TrimHelper may still be required in this order. If trimming fails or the trimmed application does not work correctly, install the helper and apply the configuration described above.

# Android and MAUI

For Android and MAUI applications, use Protection Timing = After Compile.

Because this means that trimming runs after protection, disable Anti ILDASM / Suppress Decompilation and keep NecroBit, Anti Tampering, Code Virtualization, and Hide Method Calls disabled.

If the build or trimmed application still does not work correctly, also use Eziriz.Reactor.TrimHelper and the configuration described above.

Select After Compile for Android and MAUI builds
Select After Compile for Android and MAUI builds

# Why This Is Necessary

The trimming process removes code that it considers unused.

When trimming runs before protection, this can also remove references that are not used by the original application but will be required by code injected later by .NET Reactor. Eziriz.Reactor.TrimHelper keeps these required elements available. Since the protected assembly is created only after trimming has finished, all protection features can be used normally.

When trimming runs after protection, the situation is different: the trimmer modifies the already protected assembly. Some protection features rely on metadata or other values remaining unchanged, so those features must be disabled for this build order. Eziriz.Reactor.TrimHelper can additionally be used when required by the particular project or build type.

# Related topics

Build Integration Manager · ReadyToRun

Single-file publishing · Choosing protection settings