The .NET Framework and the Common Language Runtime

The Microsoft .NET Framework is an integrated and managed environment for the development and execution of your code.

Overview of the .NET Framework:

The .NET Framework is a managed, type-safe environment for application development and execution. The framework manages all aspects of the execution of your program: it allocates memory for the storage of data and instructions, grants or denies the appropriate permissions to your application, initiates and manages application execution, and manages the reallocation of memory for resources that are no longer needed. The .NET Framework consists of two main components: the common language runtime and the .NET Framework class library.

The common language runtime can be thought of as the environment that manages code execution. It provides core services, such as code compilation, memory allocation, thread management, and garbage collection. Through the common type system (CTS), it enforces strict type safety, and it ensures that code is executed in a safe environment by enforcing code access security.

The .NET Framework class library provides a collection of useful and reusable types that are designed to integrate with the common language runtime. The types provided by the .NET Framework are object-oriented and fully extensible, and allow you to seamlessly integrate your applications with the .NET Framework.

Languages and the .NET Framework:

The .NET Framework is designed for cross-language compatibility. Simply put, this means that .NET components can interact with each other no matter what language they were originally written in.

So, an application written in Microsoft Visual Basic .NET might reference a DLL file written in Microsoft C#, which in turn might access a resource written in managed Microsoft C++ or any other .NET language. This language interoperability extends to full object-oriented inheritance. A Visual Basic .NET class might be derived from a C# class, for example, or vice versa.

This level of cross-language compatibility is possible because of the common language run time. When a .NET application is compiled, it is converted from the language it was written in (Visual Basic .NET, C#, or any other .NET compliant language) to Microsoft Intermediate Language (MSIL or IL).

This is a low-level language designed to be read and understood by the common language run time. Because all .NET executables and DLLs exist as intermediate language, they can freely interoperate. The Common Language Specification defines the minimum standards that .NET language compilers must conform to, and thus ensures that any source code compiled by a .NET compiler can interoperate with the .NET Framework.

The CTS ensures type compatibility between .NET components. Because .NET applications are converted to IL prior to deployment and execution, all primitive data types are represented as .NET types. Thus, a Visual Basic Integer and a C# int are both represented in IL code as a System.Int32.

Because both languages use a common and interconvertable type system, it is possible to transfer data between components and avoid time-consuming conversions or hard-to-find errors.

Visual Studio .NET ships with with such languages as Visual Basic .NET, Visual C#, and Visual C++ with managed extensions as well as the JScript scripting language. You can also write managed code for the .NET Framework in other languages. Third party compilers exist for Fortran .NET, Cobol .NET, Perl .Net, and a host of other languages. All of these languages share the same cross-language compatibility and inheritability.

Thus you can write code for the .NET Framework in the language of your choice, and it will be able to interact with code written for the .NET Framework in any other language.

The Structure of a .NET Application:

To understand how the common language run time manages the execution of code, you must examine the structure of a .NET application. The primary unit of a .NET application is the assembly. An assembly is a self-describing collection of code, resources, and metadata.

The assembly manifest contains information about what is contained within the assembly. The assembly manifest provides

  1. Identity information, such as the name and version number of the assembly.
  2. A list of all types exposed by the assembly.
  3. A list of other assemblies required by the assembly.

A list of code access security instructions for the assembly. This includes a list of permissions required by the assembly and permissions to be denied the assembly.

Each assembly has one and only one assembly manifest, and it contains all the description information for the assembly. The assembly manifest can be contained in its own separate file, or it can be contained within one of the assembly's modules.

An assembly also contains one or more modules. A module contains the code that makes up your application or library, and metadata that describes that code. When you compile a project into an assembly, your code is converted from high-level code to IL. Because all managed code is first converted to IL code, applications written in different languages can easily interact.

For example, one developer might write an application in Visual C# that accesses a DLL in Visual Basic .NET. Both resources will be converted to IL modules before being executed, thus avoiding any language incompatibility issues.

Each module also contains a number of types. Types are templates that describe a set of data encapsulation and functionality. There are two kinds of types: reference types (classes) and value types (structures).

Each type is described to the common language run time in the assembly manifest. A type can contain fields, properties, and methods, each of which should be related to a common functionality. For example, you might have a class that represents a bank account.

It would contain fields, properties, and methods related to the functions needed to implement a bank account. A field represents storage of a particular type of data. You might have a field that stores the name of an account holder.

Properties are similar to fields, but usually provide some kind of validation when the data is set or retrieved. You might have a property that represents the balance available in an account. When an attempt is made to change the value, the property could check to see if the attempted change was greater than a predetermined limit, and if so, could disallow the change.

Methods represent behavior, such as actions taken on data stored within the class or changes to the user interface. Continuing with the bank account example, you might have a Transfer method that transfers a balance from a checking account to a savings account, or an Alert method that warns the user when his balance has fallen below a predetermined level.

Compilation and Execution of a .NET Application:

When you compile a .NET application, it is not compiled to binary machine code; rather, it is converted to IL, which is a low-level set of instructions understood by the common language run time.

This is the form that your deployed application takes—one or more assemblies consisting of executable files and DLL files in IL form. At least one of these assemblies will contain an executable file that has been designated as the entry point for the application.

When execution of your program begins, the first assembly is loaded into memory. At this point, the common language run time examines the assembly manifest and determines the requirements to run the program. It examines security permissions requested by the assembly and compares them to the system's security policy.

If the system's security policy does not allow the requested permissions, the application will not be run. If the application passes the system's security policy, the common language run time executes the code. It creates a process for the application to run in and begins application execution. When execution starts, the first bit of code that needs to be executed is loaded into memory and compiled into native binary code from IL by the common language run time's Just-In-Time (JIT) compiler.

Once compiled, the code is executed and stored in memory as native code, so each portion of code is compiled only once during the execution of an application. Whenever program execution branches to code that has not yet been executed, the JIT compiler compiles it ahead of execution and stores it in memory as binary code.

This way, application performance is maximized because only the parts of a program that are executed are compiled.

Summary :

The .NET Framework is a foundation for software development. The .NET Framework consists of the common language run time, which provides many of the core services required for program execution, and the .NET base class library, which exposes a set of predeveloped classes to facilitate program development. The Common Language Specification defines a minimum set of standards that all languages using the .NET Framework must support, and the CTS ensures type compatibility between components developed in different languages.

The primary unit of a .NET application is the assembly, which consists of an assembly manifest. The assembly manifest describes the assembly and one or more modules, which contain the source code for the application.

A .NET executable is stored as an IL file. When loaded, the assembly is checked against the security policy of the local system. If it is allowed to run, the first assembly is loaded into memory and JIT compiled into native binary code where it is stored for the remainder of the program's execution.












No comments:

Post a Comment