Master C# Logo banner
Welcome to MasterCSharp.com - Master C#, the easy way... - by Saurabh Nandu

 


Assembly and Module - Part2

Add Comment
 

 
<span class=wboxheado>Introduction</span><br> In my previous article on <a href="http://www.mastercsharp.com/article.aspx?ArticleID=2&amp;&amp;TopicID=11" class="wbox">Assembly and Module</a>, I gave you a brief introduction on the features and differences between the two concepts. In this article on the request of <b>why_zjs - China</b> (I don't have your name pal! ) I will explore more into the actual part of compiling Assemblies and Modules. I will also use the tool <b> ILDASM</b> to show you the actual difference between the two. <p><span class=wboxheado>ILDASM - Tool</span><br> ILDASM in short stands for IL (Microsoft Intermediate Language) Disassembler. This is a very powerful tool which makes use of <i> Reflection</i> internally to show the different classes and class members contained within an assembly or a module. ILDASM also shows the Metadata contained within the assembly/module. It is very useful in situations you have the assembly but don't know its contents, just use ILDASM to discover the different classes their access modifiers, different class members, their parameters and return types.<br> To run the ILDASM tool go to <i>Start -&gt; Run</i> within the dialog type <i>ILDASM</i> and press <i>Enter</i>. To view the contents of assembly/module choose the assembly/module from the <i>File -&gt;Open</i> dialog of ILDASM. <b> Note:</b> ILDASM can only be used to view the contents of a .NET PE (Exe/Dll) file, it cannot be used to view the contents of a regular PE file.</p> <p><b>Example 1:</b> Module<br> Let's get started...&nbsp;<br> To start up, I have written a small class (given below) and saved it as FirstClass.cs.&nbsp;This class is a public class with just one method.</p> <table border="0" width="100%" class="code"> <tr> <td width="100%"><pre>using System; public class FirstClass { public void PrintMessage() { Console.WriteLine(&quot;I am First Class&quot;); } }</pre></td> </tr> </table> <p>Now we first compile this class into a Module, the compilation string will be:<br> <b><i> csc /t:module FirstClass.cs<br> </i></b><br> This will create a <b>FirstClass.netmodule</b> file in the directory you ran the compiler. <b> <br> Note:</b> We use the <b>/t:module</b> compiler switch to compile a module.<br> Now let's examine this module, fire up the ILDASM tool, and select the FirstClass.netmodule file from <i>File -&gt; Open</i>&quot;dialog of the ILDASM tool. There is one hitch here although, ILDASM does not shown the *.netmodule extension in the Open File dialon.<br> To workaround this, select <i>Any type (*.*)</i>&quot; from the <i>Types of Files</i> dropdown in the <i>Open File</i> Dialog and then select the module.</p> <p>Once you have the right file selected you should be able to see something like below</p> <div align="center"> <table border="0" class="outline"> <tr> <td width="100%"> <img border="0" src="../../img/assembly2-1.gif" width="470" height="212"></td> </tr> </table><b>Figure 1:</b> ILDASM: FirstClass Module </div><br>If you remember, in the last article I had stated that modules don't have an <b>Assembly Manifest</b> but in ILDASM (the above figure too) shows that our module has a <b>Manifest</b>. How is this possible?? I would like you to mark my words carefully, I said, &quot;<i>modules don't have Assembly Manifest</i>&quot; that does not mean that modules don't have a manifest! There's a big difference between a Manifest and an Assembly Manifest as we shall see below. <br> So what does the the Manifest of a module contain? The easiest way is to <b>Double-Click</b> on the <b>Manifest</b> item in ILDASM and find out yourself!<br> <br> <div align="center"> <table border="0" class="outline"> <tr> <td width="100%"> <img border="0" src="../../img/assembly2-2.gif" width="496" height="257"></td> </tr> </table> <b> Figure 2:</b> ILDASM: Manifest of the FirstClass Module </div><br>Your module manifest window should look like figure 2. I know that more than half of it won't make any sense to you (it doesn't make any sense to me either!! ), but we can notice a few important things. Firstly, <b>.assembly extern mscorlib</b> section defines, that this module is using some classes exported from the assembly <b>mscorlib</b> (mscorlib.dll). Can you find out which classes from the mscorlib assembly have been used in our example????&nbsp;<br> 1) System.Console - class is placed within the mscorlib assembly and<br> 2) System.Object - why? All .NET classes derive<font color="#FF0000"> </font>for System.Object, remember !!!<br> <br> Also within the extern section we find <b>.ver 1:0:3300:0</b>, this is the exact version of the mscorlib assembly against which our class has been compiled, from this we can make out how the versioning policy of the .NET Framework works.&nbsp; Even if in the future&nbsp;<font color="#FF0000"> </font>another build of the mscorlib assembly is installed, still the .NET runtime will load the correct version of the assembly i.e. 1:0:3300:0 version while running this&nbsp;module. This hard-coding of the assembly version within the Manifest rids the .NET Platform the buggy <b>Windows Registry</b>, since now the .NET PE files are <i> self-describing</i> and contain all the information required by the runtime in the form of Metadata stored in its manifest. <p><b>Example 2:</b> Assembly<br> In this example we use the same FirstClass class but this time we compile it as an assembly. So now our compilation string changes to:<br> <b><i> csc /t:library FirstClass.cs</i></b><br> <br> The above will compile a library Dll called FirstClass.dll in the directory you ran the command.<br> Again we fire up the ILDASM tool to examine this assembly (I hope by now you know how to load the library dll into ILDASM??). On first looks it might seem the same as the module definition, but the real magic is within the Manifest, so without any further delay double-click the Manifest item within the ILDASM tool.</p> <div align="center"> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <img border="0" src="../../img/assembly2-3.gif" width="480" height="350"></td> </tr> </table><b>Figure 3:</b> ILDASM: Manifest of FirstClass Assembly </div><br>The above snap-shot of the Manifest makes the difference between Assemblies and Modules clear! As marked in green above, the assembly contains an '<b>Assembly Manifest</b>'. This Assembly Manifest contains the <b>Hash</b> of the class and the <b>Version</b> of the assembly. Since I have not specified any versioning information during compilation a default version of <b>0:0:0:0</b> is used by the compiler. It's this Assembly Manifest used by the .NET Runtime to determine the version other details of the Assembly.&nbsp;<br> As I have mentioned earlier .NET Platform follows strict versioning, if the Assembly Manifest is missing (like in the case of Modules) the runtime cannot know which version of the file to load, hence it can't proceed any further! Hence its said that you cannot use Modules directly and they can only be accessed via assemblies.<p><b>Example 3:</b> Consuming a Module<br> Since modules can't be used directly you have to create an assembly that references the module. Let's take one more example to learn to consume Modules. Write the below code into Notepad and save it as <b>MainClient.cs</b>.</p> <table border="0" width="100%" class="code"> <tr> <td width="100%"><pre>public class MainClient { public static void Main() { FirstClass fc = new FirstClass(); fc.PrintMessage(); } }</pre></td> </tr> </table> <p>Firstly, we will compile the application <b>referencing</b> the module. Compile the above file with the compilation string:<br> <b><i> csc /addmodule:FirstClass.netmodule MainClient.cs</i></b><br> <br> This will compile a Console Application MainClient.exe. <br> Note that the compiler option <b>/addmodule</b> is used to reference a module. <br> Go to the command prompt, navigate to the folder that hosts the application and run it, you should see the output as&nbsp;<br> <b>I am First Class</b>.<br> To understand what happens internally, open the MainClient.exe file in ILDASM and Double-Click the Manifest item.</p> <div align="center"> <table border="1" cellspacing="0" cellpadding="0"> <tr> <td width="100%"> <img border="0" src="../../img/assembly2-4.gif" width="517" height="515"></td> </tr> </table><b>Figure 4:</b> ILDASM: Manifest of MainClass </div><br>As its clear from the above screen-shot, that when we reference a Module, then the Assembly Manifest contains extra metadata for the referenced module as well as for the classes contained within it. Remember that we have only referenced the Module within our assembly, hence while distributing our application we have to copy the FirstClass.netmodule too, or the application won't run! In this example we built an application in which we have one Assembly and one Module, since the Assembly has Metadata not only of itself but also of the Module/s it references it can be said that <b><i>Assemblies can span Multiple Physical Files</i></b>. <p><span class=wboxheado>Conclusion</span><br> From the above example it is clear that both Modules and Assemblies have Manifests. This Manifest contains Metadata information of the Module/Assembly as well as it contains detailed Metadata of other assemblies/modules references (exported). It's the Assembly Manifest which differentiates between an Assembly and a Module.&nbsp;<br> The Assembly Manifest contains important information required by the .NET Runtime to execute the IL code within the PE file successfully!&nbsp;<br> We also saw how Versioning support has been built into the .NET PE files. Some curious learners among you might have also noticed that Referencing Assemblies/Modules only adds the reference to the assembly/module in your code and the code in the external file does not get imported into your code. This is the reason that you have to supply all the Assemblies/Modules you use in your Application along with the Assembly that builds you application.</p> <p>Now, using ILDASM isn't so hard is it? Play with it and you will learn a lot of things :)

Comments

Add Comment