.NET Framework architecture

High- and low- level programming languages

Before we delve into the .NET Framework architecture itself, let us first understand the reasons for which the framework was initially created. We will start with the difference between high- and low- level programming languages.

In general, the lower the programming language you use, the closer you are to the underlying CPU, where the code is running. This basically allows you to use the best set of commands (instructions) for the CPU that your code is using. If you do this right and select the most optimal set of instructions for your particular CPU, your program can never be faster on the same hardware.

To select the most optimal set of instructions, developers require a very thorough knowledge of the system their code is going to run on. Any mistake a developer makes at this level may not only kill the advantage of the highest processing speed, but can also cause the program to be unstable and possibly even jeopardize the stability of the entire system where the program is running.

As all the hardware-specific instructions have to be manually entered, coding in very low-level programming language is also much more time-consuming than in high-level ones.

The high-level programming languages are based on a certain type of abstraction. This allows for the code to be more human readable, less error-prone and more stable. In addition to that, the whole application can be developed in a much shorter time frame. All these advantages come at only one cost – a slightly diminished processing speed. This comes from the fact that in high-level languages the developer does not have the same full control over which instructions are being sent to the hardware itself.

Today, when the speed of computer hardware doubles approximately every two years, the advantages of high-level programming languages usually outweigh its single disadvantage many times over. This is true for almost all types of software applications and that is why today most of these applications are written in high level programming languages such as C/C++ rather than Assembler for instance.

Higher than C/C++

With the increasing need for more and more applications to be built in the past couple of decades, not even C/C++ is now considered to be high-level-enough language.

First, even though this cannot be compared to programming in Assembler, inexperienced developers are still able to make critical mistakes in C/C++. Such mistakes can still jeopardize the stability of the whole system. The main problem is that C/C++ allows the developers to directly access the system memory, effectively allowing them to rewrite part of memory that belongs to a different process running on the same system. This can be done both, unintentionally as a mistake or intentionally as an attempt at the security of the system.

Second, as there are more and more applications created now than ever before, developers often find themselves spending a lot of time writing the same blocks of code over and over. To make the development process faster, it was important to put these blocks of code in some type of a common library for all developers to use.

Developers tried to resolve this issue by creating so called shared libraries. These libraries were installed in a shared directory on the target system and provided a way for other applications to share them. This, looking good at the beginning, unfortunately created another problem. As these shared libraries evolved from version to version, inevitably different programs were attuned to different versions of these libraries as well. Every time a new application was installed, it replaced the shared library with another version. While the application that was installed last worked flawlessly, the existing applications, relying on the older version of the shared library, suddenly stopped working. This is something that later became known as “DLL hell”.

Finally, before any application created in a high-level language can run, it needs to be translated into a machine specific instructions. This translation, known as compilation, is performed on the developer’s machine and needs to be done in such a way that the target machine will understand it and be able to run it. This effectively means that the same code has to be compiled on the developer’s machine again and again for every different target hardware platform.

As these hardware platforms continue to evolve over time, they provide new ways to run code faster and better through the usage of special new instructions. Unfortunately the compiler almost never chooses to use these new instructions as the complied code could then not be run on machines that are older. The only solution would be to compile the code not only for every different platform, but also for every version of these platforms. That would however soon become impractical and the compiler therefore compiles the code to be as backwards compatible as possible, forgoing all the new features of the hardware platform in the process.

.NET Framework to the rescue

Finally, we are getting to the .NET Framework itself. Let us see how it sets out to resolve all of the issues mentioned above.

Compilation and managed code

Right at the heart of .NET Framework we have something called CLR (Common Language Runtime). CLR is in charge of both, code compilation as well as running it.

The compilation in .NET Framework is two-phase. First, the code written in a specific .NET Framework language, for example C#, is translated into an intermediate language called CIL (Common Intermediate Language) or MSIL (Microsoft Intermediate Language). This phase happens directly on the developer’s computer.

The second phase of the compilation happens directly on the computer where the code is supposed to run. This is possible thanks to the .NET Framework runtime libraries being already installed on the system. These libraries are specific to the target machine and will compile the code directly for and tailored to the machine where the code will be run.

In order to speed up the compilation process, a Just In Time (JIT) compilation is used. This means that when the application starts, only its necessary parts get compiled and it can start almost instantaneously. At a later time, when the application requests anything that has not yet been compiled, the compiler gets it compiled on the fly.

Since the code is effectively managed by the compiler when it is being run on the target machine, it is called “managed code”. Compared to classic “unmanaged code”, the host system can now see what the code is about to perform and can use it to implement additional security measures – such as prevent it from accessing the registry or other specific system resources. All this is under the discretion and full control of the target system and brings yet another level of code security into the .NET Framework world.

Base class libraries

Apart from the CLR the .NET Framework also contains several Base Class Libraries (BCLs). These libraries contain an already implemented and well tested code for many common tasks. Thanks to BCLs, tasks such as working with the database, manipulating XML, downloading content from the web, etc., now only take a couple lines of code.

Global assembly cache

Even though BCLs offer many of the commonly used functionalities, there is still a need for sharing other custom libraries across multiple .NET Framework applications. In order to avoid the already mentioned “DLL hell”, the .NET Framework allows each developer to digitally sign their library (also called assembly), together with its version number, and give it a unique “strong” name.

Once an assembly has its strong name, it can be registered in a Global Assembly Cache (GAC). The GAC is basically a list of assemblies with a strong name installed on a system. These assemblies are made available to any application that requests them by their strong name. This way the application can be sure to get the right assembly every time.

The GAC not only avoids the conflicts between different versions of the same assembly but also adds an additional security that comes from digitally signing the assembly. With this digital signature, no one can purposely substitute the original assembly the application expects by a different, possibly dangerous implementation.

Right tool for the right job

In the text above we have praised the .NET Framework, pointing out all of its advantages compared to older or low-level languages. We have also stressed out the importance of the Just In Time compilation with regards to security as well as platform independence.

Thanks to all of this, by using .NET Framework, you can create applications for wide variety of devices more rapidly and more safely than ever before. All this by sacrificing only something like a single-digit percent of performance compared to lower-level languages.

That being said, the .NET Framework should be a preferred platform for developing standard business applications, small to medium-size games, web servers, etc.

If however you are building applications demanding the highest performance, large-size games, graphic intensive applications or device drivers, you will be better off staying clear of the .NET world and choosing a more low level language.

As with everything else, remember that there is no silver bullet. Always make sure to pick the right tool for the right job!

.NET Framework languages

The .NET Framework is a platform for building applications - it is not a language.

You can use many languages to target .NET Framework. The most popular ones are C# and Visual Basic .NET.

Thanks to the fact that all languages in the end get translated into the Common Intermediate Language, selecting the language depends mostly on developer’s personal preference. In fact, the languages are so interchangeable that you can even create a single application by mixing any of the languages!

On the other hand, even though there is such a freedom in selecting the language, it is usually common to use only one language within a development team – so, make sure you pick the right one to learn!

The single most popular language for the .NET Framework is C#. The language syntax is similar to C/C++ or Java and it has been created and specifically designed for the .NET Framework platform from the ground up.

To show you how the language looks like, this is an example of a simple “Hello world” application using C#:

// Allow easy reference to the System namespace classes.
using System;

// This class exists only to house the entry point.
class MainApp
    // The static method, Main, is the application's entry point.
    public static void Main()
        // Write text to the console.
        Console.WriteLine("Hello World using C#!");

Due to a large popularity of Basic language, the .NET Framework also allows to use Visual Basic .NET. The Visual Basic gained its popularity for its simplicity and easy to understand syntax couple years ago when it has been a standalone programming platform. Together with the creation of the .NET Framework Microsoft decided to discontinue the development of the original Visual Basic and provide the migration path through the new language – Visual Basic .NET. Even though the languages share similar syntax, many of the advanced features are so different that in order to port the old Visual Basic application into .NET, it had to be completely rewritten.

This is an example of a simple “Hello world” application using Visual Basic .NET:

' Allow easy reference to the System namespace classes.
Imports System
' This module houses the application's entry point.
Public Module modmain
    ' Main is the application's entry point.
    Sub Main()
        ' Write text to the console.
        Console.WriteLine("Hello World using Visual Basic!")
    End Sub
End Module

In this online school, as its name suggests, we will focus on the C# language.

Visual Studio

Coding for the .NET Framework is as easy as opening a text editor of your choice, typing the code in and having it compiled by a freely distributed .NET Framework compiler.

While this approach is certainly possible it is not the most comfortable one. For the best coding experience it is better to use a dedicated tool that can take care of code syntax highlighting, provide useful information through IntelliSense, have an advanced debugger, etc. Regardless of the language you choose for the .NET Framework development, this tool is called Visual Studio.

There are many versions of Visual Studio available. They range from free versions to the most advanced versions for large teams in large corporations costing huge amount of money.

Up to 2014 the free editions were called Express editions. There was always a single Express edition for a single language or technology – Microsoft Visual C# Express for example.

By the end of 2014 Microsoft discontinued the Express editions and announced a new Visual Studio edition called Community edition. This Community edition can be used to develop in any .NET Framework language and has all the features required to build any .NET Framework application. The only limitations are license-based. The edition itself can be used on commercial projects in companies provided they only use a maximum of five installations. In open source projects, the edition can be used without any limitations.

Visual Studio Professional is the first paid-for edition. It has exactly the same features as the Community edition except there are no license-based limitations as to the number of installations within a company.

The higher editions of Visual Studio add other features. These features are mostly beneficial to testers, architects and other specific roles in large teams. They also provide functionality for better cooperation and integration in large teams. These editions find their application mainly in large corporations as they also come with a corporate-like price tag.

The history of .NET Framework

The inception of .NET Framework itself dates back to year 2000. It took another two years for the first version to appear. Currently the latest version is 4.5.2.

There is a different versioning system for the .NET Framework itself, for its languages as well as for Visual Studio. The following table tries to summarize the platform development so far.

Year.NET FWVB .NETC# .NETVisual Studio
2002 1 7 1 2002
2003 1.1 7.1   2003
2005 2 8 2 2005
2006 3      
2007 3.5 9 3 2008
2010 4 10 4 2010
2012 4.5 11 5 2012
2013 4.5.1 12   2013
2014 4.5.2      
(2015) 4.6 14 6 2015

Continue to: First console application

Go up to: Basics

Should you have any questions or found a mistake that needs correcting, feel free to send an email to: info [at] mycsharp [dot] net

Advertisements :