Mixing C# and VB.NET in one assembly

Development, MSBuild, CSMVPs comments

A couple of weeks ago Jayson Knight invited me to join the CSMVP's' CSModules package. This project was created to incorporate several CSModules written by CS MVP's. So I bought into that project by bringing along my Akismet spam rule.

At that point in time, for each CSModule there was a single Visual Studio project, all bound together in a Visual Studio solution. But our goal was to incorporate all modules into a single assembly, so the user only has to copy one DLL to his /bin web folder.

My first idea was to put all sources into a single project. However, since every CS MVP wrote his module in his favorite language, there were both C# and VB.NET projects. Unfortunately, in Visual Studio projects have a certain type supporting only a single language.

But luckily, even if there's no support by the IDE, you still can compile different .NET languages into one assembly. The solution are modules. A module is a unit of compilation, comparable to .obj files in C++. It can't stand by its own, but must be linked into an assembly before it can be used. Basically, a module is an assembly without a manifest. You can get more details on MSDN at .netmodule Files as Linker Input. Additionally I recommend reading Junfeng Zhang's Netmodule vs. Assembly and Multimodule Assemblies.

Knowing the concept of modules, I was able to write a MSBuild project file to compile all CSModules into a single assembly. Here's an (extremely) simplified version:

  <!-- Target folders -->

  <!-- Specify the sources to include, excluding any assembly info's -->
      Exclude="$(SourcePath)/**/assemblyinfo.vb;$(SourcePath)/**/My Project/*"/>

  <!-- Specify all referenced assembly -->
    <References Include="lib/2.1 RTM/*.dll" />

  <!-- Target files -->

  <!-- builds the CSMVPs.CSModules assembly -->

    <!-- compile C# sources -->
    <!-- compile VB.NET sources -->

    <!-- link the C# and VB.NET modules -->
      Command="link /dll /ltcg /out:$(OutputModule).dll *.netmodule" />