How to merge multiple. NET assembly and multiple. net programs
Anyone who once looked for a solution to merge multiple programs into one file may have heard of such tools as ILMerge and SmartAssembly.
Another well-known solution is to embed DLL as a resource (if you are interested, here is a wonderful article describing this solution: Load DLL [^] From embedded resources).
In some cases, I realized that these methods are necessary. if we have the source code of these assemblies, we can get a perfect combination of these items by importing all these source code files into a project during compilation.
Here I will try to briefly describe how to do it.
For demonstration, let's assume that we have a console application (this is our main program) that references and uses two class libraries (our second-level program ), we want to combine them into a file:
We constructed this solution based on our ideas and obtained these three programs:
Note the MyExecutable project file (MyExecutable. csproj) is an XML-based file. If we view its content, we will find some ItemGroup nodes. these nodes contain sub-elements that define the build process input. these sub-elements can reference the resource files of the application to be compiled, or some resources to be copied, and the Assembly to be included in the build process (if you are interested in this, you can learn more about Visual Studio project files on MSDN MSBuild ).
Now let's locate the ItemGroup node, which references the assembly to be included:
<ItemGroup>
<ProjectReference Include="..\MyLibrary1\MyLibrary1.csproj">
<Project>{ea53ca82-13d7-4be1-b95a-4d9d7853d46e}</Project>
<Name>MyLibrary1</Name>
</ProjectReference>
<ProjectReference Include="..\MyLibrary2\MyLibrary2.csproj">
<Project>{c31d21f3-e86a-4581-b4e8-acae6644d19e}</Project>
<Name>MyLibrary2</Name>
</ProjectReference>
</ItemGroup>
Here, we will add a condition indicating that MSBuild will use these project references when building MyExecutable in Debug mode:
<ItemGroupCondition="'$(Configuration)'=='Debug'">
For the Release mode, all source code files from MyLibrary1 and MyLibrary2 are included and compiled. we will use a wildcard ("\**\*. cs). All CS files in the directory and Its subdirectories are included. the wildcard text also contains some resource code files we do not want (TemporaryGeneratedFile _ [guid] In the obj folder. cs and AssemblyInfo in the Property folder. cs files) So we will exclude them:
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
<Compile Include="..\MyLibrary1\**\*.cs"
Exclude="..\MyLibrary1\Properties\AssemblyInfo.cs;
..\MyLibrary1\obj\**;
..\MyLibrary1\bin\**">
<Link>MyLibrary1\%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Compile>
<Compile Include="..\MyLibrary2\**\*.cs"
Exclude="..\MyLibrary2\Properties\AssemblyInfo.cs;
..\MyLibrary2\obj\**;
..\MyLibrary2\bin\**">
<Link>MyLibrary2\%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Compile>
</ItemGroup>
In this way, let's save the changes in MyExecutable. csproj and rebuild the solution in release mode:
The last thing I want to emphasize is that we need to compile all the Assembly source files to a project in the form, and the project must be able to compile those files. therefore, consider the following:
In order to build successfully, the main program must have all references, resources, and settings of the level-2 program.
All the assemblies must be written in the same. NET language.
The above is all the content described in this article. I hope you will like it.