ASP.NET 2.0 compilation model allows generating multiple assemblies for each page and user control. This can be a bad thing and a good thing. Bad thing as it takes freaking too long to build your project. I have expressed my anger in this post. Anyway, the good thing is that now you can treat your user control as a server control since, it is contained inside a separate assembly. Since, each control is deployed as a separate assembly you end up with crazy names like the following:
App_Web_bluetextbox.ascx.cdcab7d2.dll
App_Web_yellowtextbox.ascx.cdcab7d2.dll
App_Web_default.aspx.cdcab7d2.dll
Now, if want to use bluetextbox control I can simply register is on my page using the following code:
<%@ Register Assembly="App_Web_bluetextbox.ascx.cdcab7d2" Namespace="ASP" TagPrefix="Blue" %>
This will work just fine but now it I have to use yellowtextbox then I have to repeat the process again this time using the App_Web_yellowtextbox.ascx.cdcab7d2.dll assembly. We need a way to join all the assemblies together and give them a clearer name.
ILMerge tool comes to our rescue. The purpose of ILMerge is to combine multiple assemblies together into one single assembly.
Let’s see how we can use ILMerge under different scenarios:
ILMerge Command Line Option:
The simplest way is to use ILMerge is to use the command line options. Check out the screen shot below which shows how to merge two assemblies together into “MyControlsLibrary.dll”.

This will produce a resultant assembly called “MyControlsLibrary”. You can use Reflector to see what’s inside the “MyControlsLibrary”.

Okay! So that is cool since now we can just use a single assembly in your projects without having to worry about adding multiple assemblies.
But, there is a problem when using the command line tool. It does not allow merging the assemblies unless the merging assembly name is supplied. I don’t really want to specify the names of all the assemblies that I need to merge. What if there are 50 assemblies?
Programmatically Merging Assemblies:
This fiasco led me to create a simple application that reads all the “dlls” and then fire up the ILMerge tool to merge them together. Here is the implementation:
static void Main(string[] args)
{
string assemblyFolderPath = @"C:\Projects\UserControlToServerControl\UserControlToServerControlSolution\PrecompiledWeb\WebApps\bin";
string outputFilePath = @"C:\MyControlLibrary.dll";
string assemblyName = String.Empty;
// get the assemblies from the assembly folder path
string[] assemblies = Directory.GetFiles(assemblyFolderPath, "*.dll");
string arguments = String.Format("/t:library /out:{0} {1}", outputFilePath, String.Join(" ",assemblies));
Console.WriteLine("Starting the ILMerge Process");
System.Diagnostics.Process.Start("ILMerge.exe", arguments);
Console.WriteLin
The program reads all the assemblies inside the “bin” folder of the project then it generates the arguments list and finally calls the ILMerge tool to perform the merge operation.
This works fine but most probably you want the merge operation to be a part of your build process. So, let’s see how we can perform the same operation using Nant.
Using Nant with ILMerge:
Here is the Nant script that can be used to read the assemblies from the “bin” folder and use a foreach loop to generate the final assembly list and then execute the ILMerge tool to perform the actual merging. I have placed the ILMerge in the Windows\System32\ folder so I can access it from any directory.
<?xml version="1.0"?>
<project name ="merging" default="deploy">
<property name="ilmergePath" value="ILMerge.exe" />
<property name="mergedAssemblyName" value="ResusableControls.dll" />
<property name="assemblyFiles" value="" />
<property name="BuildRoot" value="C:\Azam\UserControlToServerControl\UserControlToServerControl\" />
<property name="ProjectName" value="MyControls" />
<property name="ProjectPath" value="${BuildRoot}\PrecompiledWeb\${ProjectName}" />
<foreach item="File" property="filename">
<in>
<items basedir="${ProjectPath}\bin">
<include name="App_Web*.dll" />
</items>
</in>
<do>
<echo message="${filename}" />
<property name="assemblyFiles" value="${assemblyFiles} ${filename}" />
</do>
</foreach>
<target name="deploy">
<exec program="${ilmergePath}" commandline="/target:library /out:${mergedAssemblyName} ${assemblyFiles}" />
</target>
</project>
Using PowerShell with ILMerge:
If you are one of those PowerShell fanatics then this is for you. I have played with PowerShell before but that was a long time ago. Here is the powershell script (Thanks to Peter Seale for helping me out with this script).
echo "cleaning the variables for fresh merge"
$dlls = ""
$assemblies = ""
$dlls = Get-ChildItem C:\Azam\UserControlToServerControl\UserControlToServerControl\PrecompiledWeb\MyControls\bin -filter "App_Web*.dll"
foreach($dll in $dlls) { $assemblies += $dll.FullName + " ";
}
echo "merging......"
cmd /c "ilmerge.exe /t:library /out:ReusableControls.dll $assemblies"
echo "merge completed!"
So, here you go now you know multiple ways to use ILMerge to merge different assemblies into one.