Assembly InsideOut – Part 2 – NetModule

This post is in continuation to my previous post

In this post we will look how to create multifile  assembly. This brings us to the concept of NetModule.

Netmodule is a unit of compilation.  A compiler may give the option to compile a collection of source files into an assembly, or a netmodule. Netmodule contains type metadata and compiled code. It does not contain an assembly manifest.

A netmodule can not be deployed alone. It has to be linked into an assembly. This can be done by using compiler’s /addmodule switch (if the compiler supports it), al.exe, or in .Net framework 2.0, link.exe. After linking, the netmodule can be deployed with the assembly. The .Net framework 2.0 link.exe can produce a single file assembly, while all the other approaches produce multi-file assemblies.

I recommend reading this article for further more information.

Process of creating multi-file assembly:

Let’s use the MSDN sample as an example.

C:\ stringer.vb

' Assembly building example in the .NET Framework SDK.
Imports System
Namespace myStringer
 Public Class Stringer
   Public Sub StringerMethod()
     Console.WriteLine("This is a line from StringerMethod.")
   End Sub
 End Class
End Namespace


using System;
using myStringer; //The namespace created in Stringer.netmodule.
class MainClientApp
  // Static method Main is the entry point method.
  public static void Main()
    Stringer myStringInstance = new Stringer();
    Console.WriteLine("Client code executes");

C:\ >vbc /t:module C:\Stringer.vb

Microsoft (R) Visual Basic .NET Compiler version 8.0.40607.16
for Microsoft (R) .NET Framework version 2.0.40607.16
Copyright (C) Microsoft Corporation 1987-2003. All rights reserved.

C:\ >csc /addmodule:Stringer.netmodule /t:module C:\Client.cs

Microsoft (R) Visual C# .NET Compiler version 8.00.40607.16
for Microsoft (R) Windows (R) .NET Framework version 2.0.40607
Copyright (C) Microsoft Corporation 2001-2003. All rights reserved.

C:\> al c:\stringer.netmodule c:\client.netmodule /main:MainClientApp.Main /out:c:\main.exe /target:exe

Microsoft (R) Assembly Linker version 10.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

Manifest of created assembly,  Blue statements shows linked modules:

// Metadata version: v4.0.30319
.module extern client.netmodule
.assembly extern mscorlib
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
.assembly extern Microsoft.VisualBasic
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_….:
.ver 10:0:0:0
.assembly main
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ….T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 0:0:0:0
.file stringer.netmodule
.hash = (FD 0C A9 48 5D 21 80 69 7E DB EF 48 77 69 C7 A0 // …H]!.i~..Hwi..
E4 81 DD 50 ) // …P
.file client.netmodule
.hash = (FA D3 E6 75 57 7D F7 11 B8 0D B2 0D 75 32 2A BD // …uW}……u2*.
20 01 41 0D ) // .A.
.class extern public myStringer.Stringer
.file stringer.netmodule
.class 0x02000002
.module main.exe
// MVID: {2C26C760-9259-4860-A2E3-3B92C68F3882}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x03300000