The point of this article is to lay down the conceptual groundwork of numerous .NET related topics such as CLR, CTS, CLS, Managed Code, JIT Compilation, Security, Assemblies, and Reflection. You will also understand the relationship between the various aspects of the .NET frameworks, such as Common Type System (CTS) and the Common Language Specification (CLS). This article discusses the advantage of the .NET framework and managed code. Here you will also overview the language-agnostic and platform-independent nature of the .NET framework.
The .NET Framework is a rare software platform for building systems on the Windows family of operating systems such as Windows 7, 8, 2003, 2008 server as well as on non-Microsoft operating systems such as Linux, Fedora, and Mac. The .NET framework is the set of platform libraries and components that constitute the .NET API. The .NET framework is factored into several components such as CLR (Virtual Machine)-that is responsible for executing managed code.
The .NET framework is an amazing convergence of many technologies such as C#,MSIL,ASP.NET, XML, ADO.NET, COM+, DCOM, VC++, Active-X, WCF, WPF, etc… We can build rich user interface desktop applications, web applications, web services and distributed applications using the .NET framework. Here is a glimpse of some core features provided courtesy of .NET:
|OOP’s support||.NET framework is entirely based on OOP principles.|
|Numerous programming Language Support||.NET supports more than 40 languages to build up .NET centric applications.|
|Interoperability||.NET applications can communicate with existing COM binaries.|
|Improved Security||Each assembly contains built-in security information that indicates who or what users or process is allowed to access them.|
|Language Integration||It supports cross-language inheritance, debugging.|
|Simple Deployment Model||No need to register a .NET created components in the registry. It also allows multiple versions of the same assembly (DLL, exe).|
|Efficient Data Access||It provides efficient access to a relational database using ADO.NET and other variety of data sources such as XML.|
|Comprehensive FCL||It dispenses a huge API to simplify the programmer’s life.|
|Language Independence||All of the languages compiled to a Common Intermediate Language.|
|Support for Web Services||It has fully integrated support for developing web services.|
Common Language Runtime?
Common Language Runtime is the backbone of the .NET framework. CLR takes care of a number of low-level executions such as application hosting, thread handling, memory management, security checks, and application performance. Its primary role is to locate, load, and manage the .NET types (class, array, object, etc.). The term service refers to a collection of services that are required to execute code. The beauty of CLR is that all .NET-supported languages can be executed under this single defined runtime layer. The spinal cord of CLR is represented by a library refers to as mscoree.dll (common object runtime execution engine). When an assembly is referenced for use, mscoree.dll is automatically loaded.
The CLR first locates the referenced assembly, and then it loads it into memory, compiles the associated IL code into platform-specific instructions, performs security-related checks, and finally executes the code.
In-Depth, the .NET compilation process completes in two stages; first, the C# code you write is compiled into an Intermediate Code (MSIL). All .NET languages are compiled into virtual identical IL code. The compiled file with IL code is referred to as Assembly.
The second level of compilation happens just before the application is executed. At this point, the IL code is compiled into a low-level native machine code. This stage is known-as Just-In-Time (JIT) Compilation. Finally .NET CLR produces the executable or library files and executes the code. Code developed and running under the control of the CLR is often termed managed code
Microsoft shared the idea of IL code from Java byte code in which IL code can be quickly translated into native machine code. In other words, by compiling to IL code, you obtain platform independence for .NET in much same way as compiling java code.
IL code is compiled (JIT compilation), whereas java byte code was interpreted. One of the advantages of java was that, on execution, the process of translating from java byte code to native executable resulted in the loss of performance. Instead of compiling the entire applications in one go; the JIT compiler simply compiles each portion of code. This is why we can expect that the execution of managed IL code will be as fast as executing native code.
IL is the backbone of every managed application. In a sense, the language is only recognized by the .NET framework is IL. To understand IL, look at the following program. Here we are creating a function with the same operation in two languages C# and VB.NET as following;
C# .Net Code
public class TestClass
public static void Main()
Public Class TestClass
Public Shared Sub Main()
If you examine their IL code produced by the .NET framework, the ILDASM.exe utility after compiling both programs is using csc.exe and vbc.exe. You will find the same IL code in both languages. Written programs as following:
Finally, the managed code enables platform independence. You can compile to IL from one language, and this compiled code should be interoperable with another IL compiled language
Common Types System
The CTS specification describes all possible data types and programming constructs supported by the runtime, specifies how these entities can interact with each other, and details how they are represented in the .NET metadata format. Types are the mechanism by which code written in one language can talk to code written in different programming languages. CTS defines the predefined data types that are available in IL code so that all languages that target the .NET CLR will produce compiled code that is based on these types.
Suppose that one of the methods is defined in the VB.net class that returns an Integer, and if we call this method in C# defined class by implementing the inheritance but C# does not have any data type of that name. So this problem is circumventing by CTS. In VB.net Integer is actually a 32-bit signed integer that maps exactly to the IL type code, known as Int32. A source level, C# refers to Int32 with the keyword int. so the compiler will simply treat the VB.net methods as if it returned an int.
<!–Note: you can explore the various languages supported by .NET framework from www.dotnetlanguages.net–>
CTS also established the rules by which assembly form, a boundary of visibility for a type. In addition, the CTS defines the rules governing inheritance, object lifetime and virtual methods, for instance, all types must be inherited from the predefined type Systems. Object;
Common Language Specification
The .NET framework was designed to support multiple languages. During the design phase of .NET, Microsoft invited many compiler vendors to build their own .NET languages. The Common Language Specification works with the CTS to ensure language interoperability. Each language expresses the same programming constructs in specific terms. For example, in VB.NET you denote string concatenation using the ampersand (&), while in C# you typically make use of plus (+) operator. So the CLS is untimely a set of rules that compilers builders must conform to if they intended their code to be compliant with other .NET supported languages. However, not all types are available to all programming languages. To build components accessible from all .NET languages, use the CLS. With the CLS, the compiler can check for valid code according to the CLS specification. With the CLSComplaint attribute, you can mark your assembly as CLS-compliant. Doing this guarantees that the classes in this assembly can be used from all .NET consumer tools. You can instruct the C# compiler as follows:
The lower-level high-performance language such as C, C++ is used to clean memory locations for occupied resources manually. For efficiency’s sake, it is better that resources are never occupied for longer than necessary, but such mechanism has one huge disadvantage–the frequency of bugs. Code that requests memory should explicitly inform the system when it is no longer required that memory. Those process often resulting in memory leaks and easily overlooked by implementing the .NET framework feature Garbage Collection. .NET runtime relies on Garbage Collection to release resources from memory automatically instead. All dynamically requested memory is allocated on the heap so when, .NET detects that the managed heap for a given process is becoming full, it calls the garbage collector. It cleans out the Reference of objects or variable running in current scope stored from heap automatically. The most important aspect of garbage collection is that it is not deterministic. You can’t guarantee when the garbage collector will be called; it would be called when CLR decides that it is needed to release the resources from memory.
An assembly contains CIL (Common Intermediate Code) code, which is conceptually similar to Java byte code. In addition to CIL instruction, assemblies also contain metadata that describes in vivid detail the characteristics of every type in the binary. The .NET metadata is always present within an assembly and is automatically generated by .NET aware language compiler. When a *.exe or *.dll is created using the .NET aware compiler, it is referred to as an assembly. Assemblies themselves are also described using metadata, which is officially termed as manifest. The manifest contains information about the current version of the assembly, culture information and a list of all externally reference assemblies that required executing the program. Technically speaking, the .NET assembly is composed of a single file or multiple file assembly. Single file assembly contains all the necessary CIL, metadata and manifest in an autonomous. On the other hand, multiple file assemblies are composed of numerous .NET binaries, each of which is called a module. If you are building an executable desktop application m the *.exe can simply be referred to as an assembly. Likewise, if you are creating a class library, then *.dll would be referred to as an assembly. The .NET assemblies can categories into Shared Assemblies and Private Assembly. Shared Assemblies are intended to be common libraries that any other application can reference them whereas Private Assemblies are the simplest type, normally ship with software and intended to be used only with that software. Reflection
It is possible to access the metadata (vivid details about types) from an assembly programmatically using the Reflection mechanism. This method is commonly used to obtain the details of attributes, although you can also use reflection, among other purposes, such as instantiating classes or calling methods. In this way, you could select classes to instantiate methods to call at runtime, rather than compile-time, based on user inputs (Dynamic Binding). Reflection allows us to perform numerous tasks such as enumerating members of a type, finding out information of types, creating and compiling new assemblies, and inspecting the custom attributes applied to the type.
Security is an essential part of any application and should be taken into consideration from the first stage of the development process. The .NET framework secures the resources by implementing various full-fledged security mechanisms; such as authentication, authorization, code access, role-based security, sandboxing and certificate security. Furthermore, the .NET framework on its own provides you with a set of base classes for implementing confidentiality and integrity through encryption and digital signature. The .NET allows you to manage security, including how .NET protects you from malicious code, how to administer security policies and how to access the security subsystems programmatically. The .NET framework security mainly revolves around code access security and role-based security. Code Access Security (CAS) reduces the risks associated with running code of dubious origin even if code is running under a superuser account. It is possible to use CAS to indicate that code should still not be permitted to perform certain types of operations. Whereas Role-Based security is based on the identity of the account under which the process is running, CLR is able to inspect code before running in order to determine required security permissions.
Open Source Nature
This article briefly comments on the platform-independent open-source nature of the .NET framework. When Microsoft released the .NET platform, they crafted a set of formal documents that describes the syntax and semantics of the CIL language which is known as Virtual Execution System. The .NET assemblies can be developed and executed on non-Microsoft operating systems such as UNIX, Mac OS, Linux, Fedora, and other various Linux distributions. The Mono project is an open-source distribution of Common Language Infrastructure that targets various Linux distribution as well as Windows and Mac OS/ iPhone devices.
This article has covered a lot of ground, briefly reviewing important aspects of the .NET framework. It started by discussing the advantages of the framework, and the compilation process executing by CLR. As you have seen, an assembly contains CIL instructions that are compiled to platform-specific instructions using the JIT compiler. This article explores the important role of CLS and CTS. You will also get the understanding of assemblies, garbage collection, reflection and security offered by Common Language Runtime.