#706 – An Application Domain Enables Application Isolation

An application domain is an environment in which an application executes and which provides for isolation between applications.  Code running in an application domain is isolated from other application domains in that it contains its own data and cannot affect code running in other application domains.

You most often run every managed (CLR) application in its own Windows process, with the process containing a single application domain.  But it’s also possible for a process to host multiple application domains.  In this case, the applications are still isolated.  If the code within one of the application domains crashes, it does not impact code in the other application domain(s).

You can think of an app domain as the Common Language Runtime’s application isolation mechanism, whereas the process is the application isolation mechanism for Windows itself.

#705 – Applications and Class Libraries

In .NET, an application is any .NET assembly that has an entry point.  Applications are packaged into a .NET process assembly, in a file with an .EXE extension.

A class library is a .NET assembly consisting of one or more types, without an entry point.  The class library is packaged into a .NET library assembly, in a file with a .DLL extension.

You start execution of a .NET application by double-clicking or opening the .exe file that contains the application.

#486 – Unnecessary Project References Are Ignored

When we wanted to use the Dog type, which was defined in a DogLibrary assembly, we added a reference to DogLibrary from the project that wanted to use the type.

We then saw that the manifest of DogApplication indicated that DogLibrary was a dependent assembly.

But notice all of the other references that show up in Visual Studio, none of which are seen in the manifest as dependencies.

When you build your project, the build system only created dependencies for referenced projects that your application actually uses.  If we change the code to comment out use of the Dog type, but instead use a Uri type, we’ll get the following manifest:

The manifest now includes a dependency on the System assembly, because that’s where the Uri type is defined.

#485 – Project References and Dependent Assemblies

In Visual Studio, you add project references to indicate that you want to use types from another assembly.  For example, a main application (e.g. DogApplication.exe) might reference a class library (e.g. DogLibrary.dll) containing types that it wants to use.  These references allow the compiler to make sure that you are using the dependent types correctly, based on the metadata contained in the referenced assembly.

When you build a project, information represented by project references is converted to assembly dependency information, stored in the manifest of the assembly that you are generating.

An assembly’s manifest contains information about all of the other assemblies that the assembly depends on.  You use the IL Disassembler to look at an assembly’s manifest.

Double-click to open the manifest and you’ll see that DogLibrary is listed as a dependent assembly–an assembly that the DogApplication assembly depends on in order to run.

#180 – The CLR Loads Assemblies on Demand

When you execute a .NET program, the CLR (Common Language Runtime) loads the assembly located in the executable and then starts executing the code in the function defined as the entry point for that assembly.

If your assembly references a second assembly, that second assembly will only get loaded if its code is invoked at runtime.

This means that it makes sense to partition your application into assemblies, based on functionality and expected use.  If running a program typically only results in 20% of its code being executed, the most efficient partitioning would be to have the remaining 80% of the code in one or more assemblies other than the main assembly.  If code in one of these assemblies is never called, the assembly is never loaded.

Loading as few assemblies as possible is desirable, because this results in a smaller memory footprint for your program.

#179 – What Is an Assembly?

As a .NET language, C# compiles code into assemblies. An assembly is a reusable piece of code, packaged into either an .exe or .dll file.  It contains IL (Intermediate Language) code that the CLR (Common Language Runtime) will compile into machine code at runtime.

An assembly contains a manifest, which defines high-level attributes of the assembly including its name, version, copyright information and an optional strong name that uniquely identifies it.

Assemblies also contain metadata, representing a complete description of all of the contained types.  The metadata includes a description of each method and property of each type implemented in the assembly, along with information about the parameters and return type.  An assembly also includes a list of other assemblies that it references.

An assembly is typically packaged as a single .exe or .dll file, but can also be spread across more than one file.

#11 – Examine IL Using Ildasm.exe

In .NET, source is compiled to an platform-neutral intermediate language called Common Intermediate Language.  The IL is later compiled into native code at runtime, running in a virtual machine.

You can examine the IL for your applications by running a tool called the IL Disassembler (ildasm.exe).  You can find ILDasm in a directory that looks something like this:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64

Alternatively, you can just type “ildasm” in the Start Menu search box in Windows 7 or Windows Vista.

ILDasm will show you three basic things:

  • A list of all classes and methods in your assembly
  • The contents of the assembly’s manifest
  • IL code for any method implemented in the assembly.

Here’s an example of what is displayed in ILDasm.