Hi there! 👋
Today I’d like to talk about one of the basic ingredients of CLR (and .NET) - the Assemblies. As usual, the infographic goes first, followed by more detailed explanaten below.
I hope that was understandable :)
As you can see - at it’s most fundamental level, assemblies are a way of packaging and distributing code. I say “at most fundamental level” because there’s a lot more going on there, but we’ll cover that when the time comes. For now, you can think of them as archives that pack one or more files inside; it’s like a .tar, in a way.
One thing you can find inside the assembly, aside from the actual code itself, is Assembly Manifest. And if you stop and think about it, you soon realize that if you have one giant blob of ones and zeroes, and those ones and zeros belong to different files - how do you know what is what? And how do you even know if the assembly is safe to use? Or who created it? Or what the version is? Too many question that beg for an answer. And the answer is simple - Manifest.
I’ll expand lot more on Manifest and what’s inside as part of the next article, but for now just keep in mind that it’s like an Identity Card for your assembly. It provides info on WHO created it, WHICH version of the assembly is it, WHAT are the external dependencies that assembly has and what are the files that are INSIDE the assembly. That’s about it in a nutshell.
Let me show you how to look into your assemblies. Because talking is cool, but seeing it in action makes all the difference in the world. First and foremost, locate your ILDASM.exe (the MS IL Dissasembler). It comes with .NET installation so you should have it somewhere around.
Let’s look into the assembly that gets produced as a result of this simple code:
using System;
namespace CsharpDllLibrary1
{
public class Class1
{
private readonly Int32 x;
public Class1(int x)
{
this.x = x;
}
public int GetOne()
{
return 1;
}
}
}
ildasm.exe CsharpDllLibrary1.dll
That’s cool, right? As you can see - there’s a Manifest, and then there’s my library namespace with a single class inside. Cool!
If you open the Manifest, you’ll see something like this:
That's a lot to digest if you’ve never encountered it. But what you see in the Manifest is basically the Table of Contents (i.e. what’s inside) plus the Identity Information (which is missing btw but more about it later on).
And if we sneak peak into GetOne() method, you will see something like this:
So in a nutshell, what’s inside the assembly is Manifest, CLR code and optional resources (which I’ll leave for some other time). I’d actually encourage you to locate ILDASM.exe on your computer, find a DLL (or EXE) that was built using some .NET language, and explore what’s inside. You will learn the most by actually doing it.
Another thing that’s interesting to mention is - how does Windows know whether the EXE or DLL contains native code? And the answer lies in - based on the header information. To be valid, EXEs and DLLs have to conform to the Portable Executable (PE) format (and I’ll write more about it as well!) and what CLR does is that it stores info inside that header that the code that follows should be run through the CLR. But again, don’t sweat over it, I’ll cover this in a separate article.
Finally, in the graphic above, I made honorable mention of Global Assembly Cache (GAC). That’s a very fancy name for a folder that holds commonly shared DLLs (e.g. .NET framework’s DLLs). GAC is one of the folders where CLR runtime looks for assemblies if they can’t be located in your program’s local folder. But there’s a trick to it - for assembly to be elligible to be inside GAC folder, it has to be Strong-named. Strong-named is yet another fancy word for a very simple thing - digitally signed file, whose identity you can verify.
If you’re not familiar with digital signing of content, well, it’s really a cool way of claiming ownership of stuff using Private/Public keys. Owner of assembly “signs” the file (think of it as placing a seal on it) with their Private key, and they provide a (public) key which can only break the seal signed with owner’s private key. It can be a bit mind-boggling but for now just think of it as a very simple & efficient way to confirm ownership of the assembly.
And that would be all I had to share for today! If you enjoyed this content, do consider subscribing. In the next few articles I will talk more about Manifest and Strong-named assemblies before moving on to discuss the Memory Management features of CLR.
Thanks for reading!
Other articles in this series: