Typically, in .NET, to merge assemblies you would use ILMerge. ILRepack is another project you can use and that has had updates recently (and a lot of activity on Github).
I’ve found it useful to merge the lot of Dlls and Exe that can compose a simple app into a single executable file (think containers but without Docker), which facilitates using and distributing it. The new
.csproj file format is a great simplification and allows for tasks (as in the previous versions) in a smaller more understandable file.
To use ILRepack in a project, here are the steps you can perform to include the task during your build:
1 – add the
ILRepack package to the project you wish to merge files in
2 – validate that the
AssemblyName element is defined in the property groups in your
3 – in the
.csproj, add the following target element
<Target Name="ILRepack" AfterTargets="Build"> <!-- The ILRepack task will grab all build ouput assemblies and merge them into a single exe file for easy distribution and integration --> <ItemGroup> <ILRepackPackage Include="$(NuGetPackageRoot)\ilrepack\*\tools\ilrepack.exe" /> <NetStandardLocation Include="$(NuGetPackageRoot)NETStandard.Library\2.0.1\build\netstandard2.0\ref" /> </ItemGroup> <Error Condition="!Exists(@(ILRepackPackage->'%(FullPath)'))" Text="You are trying to use the ILRepack package, but it is not installed or at the correct location" /> <Exec Command="@(ILRepackPackage->'%(fullpath)') /out:$(OutputPath)merged\$(AssemblyName).exe /wildcards /lib:@(NetStandardLocation) /target:exe $(OutputPath)$(AssemblyName).exe $(OutputPath)*.dll" /> </Target>
3.1 – the
NetStandardLocation element is only required if you are targeting it or including a package that targets it.
3.2 – the
/lib:@(NetStandardLocation) argument in the Exec command is only required by 3.1
3.3 – adjust the
/out argument in the command to whatever you require.
4 – If you want to include the output in a package, define the package elements in a propertyGroup and include:
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!--we do not want build outputs integrated into the resulting package, only the IL merged file --> <IsTool>True</IsTool> <IncludeBuildOutput>False</IncludeBuildOutput> </PropertyGroup> <ItemGroup> <!-- nuget package files info: --> <!--we do not want build outputs integrated into the resulting package, only the IL merged file --> <Content Include="$(OutputPath)merged\$(AssemblyName).exe" PackagePath="tools\" /> </ItemGroup>
And that’s pretty much it. If you run build, ILRepack will be executed and build the merged file, and MSBuild will also wrap it in a NuGet package if you include the packaging step.