But giving it a deeper thought, I felt something didn’t fit the picture. Every project, rather every file that we compile using the .NET Framework generates Common Intermediate Language which is used by the Common Language Runtime. It is because of this CIL that we have language interoperability in .NET. So theoretically speaking, code written in different languages should be able to exist in a single assembly.
Though I couldn’t find a way to directly add a C# file into a VB.Net project, I found a way to create a DLL from compiled VB.Net and C# code through a concept of the .NET framework called Multi Module Assemblies.
In .NET, the minimum unit of deployment is an assembly; Dynamic Link Libraries (DLLs), Executables (.exe), etc. are all assemblies. An assembly can contain multiple files like resource files, the manifest, etc. It can contain files of another type called netmodules. A netmodule is a unit of compilation. It cannot be deployed directly but can be linked into an assembly. netmodules written in different .NET languages can be linked into a single assembly.
Unfortunately Visual Studio wasn’t built for Multi Module Assemblies, hence there’s no way to create a netmodule from a project in Visual Studio. However msbuild allows us to create a netmodule from a project. There are typically three changes that have to be done to the .proj files (.fsproj, .vbproj, .csproj, etc.) for msbuild to generate a netmodule –
- Changing the OutputType to Module. Visual Studio doesn’t recognize this output type, so even when you change this in the .proj files, Visual Studio won’t be able to show it in the Project Properties.
- Exclude the AssemblyInfo file from the project. netmodules aren’t supposed to have an application manifest. If they do, the linker won’t be able to resolve which application manifest should be used when we are building an assembly from multiple netmodules.
- If one netmodule is dependent on another netmodule, a reference to the dependent module should be specified using the AddModules XML node in the .proj file. Similar to DLLs, netmodules cannot be circularly referenced.
Once the netmodules are created using msbuild, a DLL can be created from them using the Assembly Linker of the .NET framework - al /t:library /out:"path_to_dll" path_to_netmodules
With this we have a DLL which contains all the netmodules bundled into one assembly. To understand this better, let’s consider an example – I have three projects, one in F#, VB.Net and in C# under a solution called MultiLanguage.
here. I automated the .proj changes using Microsoft’s Build Engine API. You can give it a try here; it takes the .sln file as an input and modifies all the projects in the solution to generated netmodules.