ILMerge
Best Practices
.NET
Software Development
Code Merging

ILMerge Best Practices

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

ILMerge combines multiple .NET assemblies into a single output assembly, which can simplify deployment and packaging. The most important best practice, however, is to use it only when it actually fits the runtime and deployment model you are targeting, because ILMerge is mainly a .NET Framework-era tool and is not the universal answer for modern .NET packaging.

Start by Confirming ILMerge Is the Right Tool

Before discussing switches and command lines, verify the use case. ILMerge is most at home when you are working with .NET Framework assemblies and genuinely want one merged executable or DLL.

If you are targeting modern .NET, you should at least consider whether a different approach is better, such as:

  • normal multi-file deployment
  • single-file publish features in modern .NET
  • an alternative merger tool that supports your runtime model

In other words, best practice starts with "do not merge by habit."

Merge with an Explicit Primary Assembly

ILMerge needs a clear primary assembly because that assembly supplies the entry point and much of the metadata shape of the final output.

A typical command looks like this:

bash
ILMerge.exe /out:MergedApp.exe App.exe LibraryA.dll LibraryB.dll

Here, App.exe is the primary assembly. The output is a merged executable containing the app plus the listed libraries.

If strong naming matters, sign the merged result explicitly:

bash
ILMerge.exe /out:MergedApp.exe /keyfile:mykey.snk App.exe LibraryA.dll LibraryB.dll

This is important because merging changes the assembly artifact. If the originals were strong-named, the merged output usually needs to be signed again.

Use internalize Carefully

One of the most useful ILMerge options is internalize, which hides public types from merged dependencies so only your main assembly's intended public surface remains visible.

bash
ILMerge.exe /out:MergedApp.exe /internalize App.exe LibraryA.dll LibraryB.dll

This can reduce accidental API exposure, but it is not free of risk. Reflection-heavy code, plugin systems, and serializers sometimes expect types to remain publicly discoverable.

That means internalize is a deployment boundary tool, not a default switch you should always add blindly.

Test the Merged Output, Not Just the Build

ILMerge can produce a successful output file that still fails later at runtime because of:

  • resource resolution issues
  • reflection assumptions
  • configuration-file expectations
  • mixed-mode or unsupported assemblies

A good validation loop is:

  1. build the original app
  2. merge the assemblies
  3. run integration tests against the merged artifact
  4. inspect the output with a decompiler if needed

If the application uses WPF, WinForms designers, or embedded resources, this runtime validation becomes even more important.

Keep the Dependency Graph Understandable

Merging assemblies does not remove the need to understand dependencies. In fact, it often makes mistakes harder to debug later because the boundaries are less visible.

A small build script example is often cleaner than a manually repeated command:

xml
<Target Name="AfterBuild">
  <Exec Command="ILMerge.exe /out:$(OutputPath)MergedApp.exe $(OutputPath)App.exe $(OutputPath)LibraryA.dll $(OutputPath)LibraryB.dll" />
</Target>

The point is not the exact XML. The point is that the merge step should be deterministic and checked into source control rather than retyped by hand on a developer machine.

Common Pitfalls

The biggest mistake is trying to use ILMerge for scenarios it does not support well, especially modern .NET deployment patterns that already have better native packaging options.

Another issue is merging assemblies that rely heavily on reflection, resource probing, or dynamically loaded plugins and then being surprised when runtime behavior changes. The merged assembly boundary is different from the original one.

Developers also sometimes forget to re-sign the merged output or to preserve versioning expectations. If the merged artifact is part of a signed or version-sensitive pipeline, that oversight causes downstream failures.

Finally, do not assume a successful merge means a correct deployment. Always test the merged binary as the real deliverable, not just the pre-merge project output.

Summary

  • Use ILMerge only when it truly matches the runtime and deployment model you need.
  • Choose a clear primary assembly and sign the merged output when strong naming matters.
  • Treat internalize as a deliberate encapsulation choice, not an automatic default.
  • Automate the merge step in the build so it is reproducible.
  • Validate the merged artifact at runtime, especially for reflection, resources, and UI-heavy apps.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.