An assembly is the functional unit of sharing and reuse in the Common Language Runtime. It is the equivalent of JAR (Java Archive) files of Java.
Assembly is a collection of physical files package in a .CAB format or newly introduced .MSI file format. The assemblies contained in a .CAB or .MSI files are called static assemblies, they include .NET Framework types (interfaces and classes) as well as resources for the assembly (bitmaps, JPEG files, resource files, etc.). They also include metadata that eliminates the need of IDL file descriptors, which were required for describing COM components.
The Common Language Runtime also provide API's that script engines use to create dynamic assemblies when executing scripts. These assemblies are run directly and are never saved to disk.
Microsoft has greatly diminished the role of Windows Registry system with introduction of assemblies concept, which is an adaptation of Java's JAR deployment technology.
Assemblies is an adaptation, but not a copy of Java's JAR technology. It has been improved upon in some ways, for example it has introduced a versioning system. However, since the .NET framework is skewed towards the Windows architecture some of the Java's JAR portability features may have been sacrificed.
Again, similar to JAR files, the assemblies too contain an entity called
manifest. However, manifest in .NET framework plays somewhat wider role. Manifest is a metadata describing the inter-relationship between the entities contained in the assemblies like managed code, images and multimedia resources. Manifest also specifies versioning information.
The manifest is basically a deployment descriptor, having XML syntax. Java programmers can relate it with J2EE (Java 2 Enterprise Edition) deployment descriptors for EjB (Enterprise Java Beans) applications.
The Microsoft documentation stress that assemblies are \"logical dlls\". This may be a reasonable paradigm for VB or C++ programmers, but Java programmers will find it easier, if we visualize assemblies as an extension of JAR concept. However, unlike JAR, each assembly can have only one entry point defined, which can be either DllMain, WinMain, or Main.
As stated earlier, Assemblies have a manifest metadata. This contains version and digitally signed information. This purports to implement version control and authentication of the software developer. Version and authentication procedure is carried out by the runtime during loading the assembly into the code execution area.
Again, much like Java's trusted lib. concept, .NET Assemblies can be placed in secured area called
global assembly cache. This area is equivalent to trusted class path of Java. Only system administrators can install or deinstall Assemblies from the global assembly cache. There is a place for downloaded or transient Assemblies called
downloaded assembly cache. The Assemblies loaded from global assembly cache run outside the sandbox and have faster load time as well as enjoy more freedom to access file system resources. The Assemblies loaded from the downloaded cache area are subject to more security checks, therefore are slower to load and since they run inside the sandbox; enjoy much less privileges.
Assemblies manifests also contain information regarding sharing of code by different Applications and Application Domains.
To summarize, the Operating System can have multiple applications running simultaneously, each such application occupies a separate Win32 process and can contain multiple Application Domains. An Application Domain can be constructed from multiple assemblies.
The Common Language Runtime provides the infrastructure that enables execution to take place as well as a variety of services that can be used during execution. Before a method can be executed, it must be compiled to processor specific code. Each method for which MSIL has been generated is JIT compiled when it is called for the first time, then executed. The next time the method is executed, the existing JIT compiled native code is executed. The process of JIT compiling and then executing the code is repeated until execution is complete.
As mentioned earlier, the recompilation can be avoided by compiling the code during installation into native executable code.
During execution, managed code receives services such as automatic memory management, security, interoperability with unmanaged code, cross language debugging support, and enhanced deployment and versioning support.
Before Intermediate Language (IL) can be executed, it must be converted by a .NET Framework Just In Time (JIT) compiler to native code, which is CPU specific code that runs on the same computer architecture that the JIT compiler is running on.
Microsoft's designers insist that the runtime never interprets any language, it always executes native code, only conversion to native form may be deferred. Even the scripting languages like VBScript are now compiled and executed!
The idea behind JIT compilation recognizes the fact that some code may never get called during execution; therefore, rather than using time and memory to convert all of the MSIL in a PE (portable executable) file to native code, it converts the Intermediate Language as it is needed during execution and store the resulting native code so that it is accessible for subsequent calls.
The loader creates and attaches a stub to each of the type's methods when the type is loaded; on the initial call to the method, the stub passes control to the JIT compiler, which converts the MSIL for that method into native code and modifies the stub to direct execution to the location of the native code. Subsequent calls of the JIT compiled method proceed directly to the native code that was previously generated, reducing the time it takes to JIT compile and execute the code.
The compilation process (JIT or during installation time) converts the Intermediate Language (IL) to native code. The code however, must pass a verification process. Verification examines the Intermediate Language (IL) and metadata to see whether the code is type safe, that is, it accesses only the authorized memory locations, Identities are what they claim to be and reference to a type is compatible with the type referenced. These features protects the application from bugs and viruses.
During the verification process, Intermediate Language (IL) code is examined in an attempt to confirm that the code can access memory locations and call methods only through properly defined types.
Due to design limitation of some programming languages, like 'C', it's compilers may not be able to produce verifiable type safe codes, such codes can only be executed from trusted area.
The runtime is typically started and managed by environments like ASP.NET, IE or the Windows Shell. These hosting environments run managed code on behalf of the user and take advantage of the application isolation features provided by application domains. In fact it is the host that determines where the application domain boundaries lie and in what application domain user code is run in. The Common Language Runtime provides a set of classes and interfaces used by hosts to create and manage Application Domains.
There are five Common Language Runtime hosts:
ASP.NET - ASP.NET creates application domains to run user code. Application domains are created per application as defined by the web server.
Internet Explorer - IE creates an application domain per site.
Windows Shell EXE - Each application that is launched from the command line runs in a separate application domain.
VBA - VBA runs the script code contained in an Office document in an application domain.
Windows Forms Designer - The Windows Forms Designer places each form the user is building in a separate application domain. When the user edits the form and rebuilds, Windows Forms shuts down the old application domain, recompiles the code and runs it in a new application domain.