Before you read the rest of this post, and committing yourself to use ILMerge, read this post by Jeremy D. Miller and check if you currently do not have more assemblies on your solution than you should. Cutting down the number of projects by merging existing ones is always a better solution than using ILMerge. It will significantly decrease your build times! If you still think that using ILMerge is for you please go ahead and read.
I am working on a project that references several DLL’s provided by a framework that has been developed, by my company, for many years now. Refactoring has always taken second place in the history of the project, due to the existing pressure to get features out the door. The amount of work split through several DLL’s has grown exponentially, to the point where we have around 70 DLL’s – just for the framework.
This was not a problem until we had to start a new solution that references the framework, and required to use stuff from it. Once we added the Foo class which was on Framework.Foo.dll and it had a dependency to Goo and another to Woo, we had to add three distinct references. Even though the separation between these three DLL’s seemed logic at the time, the truth is that it is not plausible they will ever be used separately, hence the idea of using ILMerge to merge the DLL’s by logical content into larger DLL’s, we ended up with 16 DLL’s which were much easier to add as a reference.
Download and install ILMerge from here (http://www.microsoft.com/downloads/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&displaylang=en).
The idea is to create a set of class library projects that will be our sample framework. Basically I added three class libraries: Framework, Framework.Math and Framework.Ux. In Framework there will be a base class Foo and its corresponding interface IFoo. IFoo will be inherited by Goo on Framework.Math, so it will have a reference to Framework. The same will happen in Framework.Ux with Woo. I also added a console application for testing purposes which shall reference the merged assembly, called MergedFramework.dll. Check the layout presented in the snapshot from the Solution Explorer.
I then set the output of all projects to a common folder – ..\bin\Debug.
The ILMerge script
In our solution output you will find the three DLL’s which will be merged into the final framework file. To merge these three using ILMerge just run:
ILMerge.exe /out:MergedFramework.dll Framework.dll /log Framework.Math.dll Framework.Ux.dll
The final DLL will be created and the corresponding PDB’s merged, so you do not lose the ability to debug your source code.
Adding the resulting Assembly as a reference
You can now add the resulting assembly to the application – ILMergeTest, and run the app. You can see that if you debug the app all the symbols point to the valid source files. Now if you change something in one of the merged DLLs it will not sort any type of effect on the final project since the DLLs are required to be merged once again.
I have added a batch script (MergeFramework.bat) that does all the merging side by side with the solution, and then I setup a pre-build step to merge the DLLs before compiling the console application. There is an obvious downside to this approach: in order for your changes in source DLL’s to take effect on the console application you will have to rebuild the console application, this happens because the merged DLL does not change when changing its sources, therefore visual studio will not assume that the console project requires to be recompiled.
Localization is another subject to be aware of. When you merge localized DLLs you will also have to merge the resource DLLs, your only consideration when merging is the resulting assembly’s name, which has to match the one of its base assembly, for instance: MergedFramework.pt-PT.dll.
You can get the project on GitHub following this link.