.Net Framework Infrastructure

This article will explain the foundation and structure of .Net framework architecture

Introduction

This article will explain the foundation and structure of .Net framework architecture. It begins with some explanations about previous most-used programming languages and frameworks and their drawbacks. Next, it talks about .Net advantages and features that made it a suitable choice for developing enterprise applications. It covers basic features of the .Net standard and their specifications.

Understanding the developing before .NET

When Microsoft began to design .Net framework, they’ve took some
other programming languages experiences into consideration. These
considerations have based on other languages drawbacks and success. It would be
useful for beginners who recently became familiar with .Net framework to know
about the other programming languages specifics and issues. Moreover, it is
useful for professional developers to remind them what difficulties motivated
the genesis of Microsoft’s current platform. (Meanwhile, not all professional developers
are familiar with all programming language structure!)

To begin with, a brief history of these decades programming
will be mentioned to understand the limitations of the previous state of affairs
of programming. Next, the numerous benefits provided by the .NET platform will
be discussed.

Programming with C/Windows API

In the past, talking about Windows family software development has
involved using of C with the Windows application programming interface (API). Although
various types of applications have been created using this technology, using
the API is a complex approach. The first problem is that C is a very laconic language. Developers
are forced to deal with manual memory management, pointer
arithmetic, and syntactical constructs. Furthermore, C is a structured languageand it doesn't provide the object-orientedapproach. Combination of many global functions and
data types defined by the Windows API to a robust complicated language; made many
buggy applications.

Programming with C++/MFC

C++ can be thought of as an object-oriented layer on top of
C. Thus, even though C++ programmers benefit from the facilities of OOP, they
still feel the painful aspects of the C language like manual memory management
and pointer arithmetic. Despite its complexity, many C++ frameworks exist
today. Regardless of the helpful assistance offered by C++-based windowing
toolkits, the fact is that C++ programming was difficultand prone to error.

Programming with Visual Basic 6.0

VB6 was popular because of its easy designer for complex UI, code libraries, and easy database accessibility. Much more than MFC, VB6
hid the complexities of the raw Windows API. Its major drawback is that it is not a fully OO language.
Indeed it is object based language.
E.g. VB6 does not allow the programmer to establish classical inheritanceand has no support for parameterized object construction.
Moreover, VB6 doesn't provide the ability to build multithreaded applicationsunless
you call low-level APIs which are complex
and dangerous.

Programming with Java

Java is an OOP language which has derived some its syntactic structure
from C++. Java’s is platform
independence language and as a language, it has many revisions for C++ unpleasant syntactical pieces.
As a platform, it provides a large number of predefined packages (Class libraries).

One issue is that by using Java, you must probably use Java and
only Java during the development cycle. Java provides little language
integration and true
cross-language integrationbecause of limited ability to access
non-Java APIs. This is against
the Java’s primary goal: “Single programming language for every need”.

Programming with COM

COM (Component Object Model) is Microsoft’s previous application
development framework and introduced in 1993 with the OLE. COM architecture tries
to build types which follow common rules. Therefore, they can end up with blocks
which are reusable binary code. These COM binary codes are called
“COM servers”. One benefit is that they are language-independent. However, there is no
support for inheritance. Thus it’s not possible to derive a new COM class. Another benefit is their location-transparentnature by
using structures like the system registry, application identifiers
(AppIDs), stubs, proxies, and COM runtime environment.
COM DLL can be placed in various locations of a server or local host.

Although COM can be considered a very successful model, it
is extremely complex in the real world. There are many issues with COM DLLs
especially when applications have been installed and uninstalled on a system many
times. These issues tragically termed as “DLL hell”. The difficulties consist
of conflicts between DLL versions
(Incompatible versions), DLLs obtaining
difficulty (DLL stomping), Incorrect
COM registration, and unnecessary DLL
copies existence.

COM assists the construction of software applications by using
different programming languages. However, its nature is not truly language-independent. Part of this complexity
comes from the fact the structures that are mixed together are completely
unrelated from the infrastructure point of view. As a result, we face a confused
mishmash of technologies. In addition, technologies type systems are not identical.
Apart from the fact that each API has its own collection of code library, even
basic data types cannot always be treated identically.

Microsoft .NET Framework

The .NET Framework is a software platformfor building systems on the Windows family
of operating systems, as well as many non-Microsoft operating systems. Among
the difficulties of other programming languages and platforms which has
mentioned, the .NET Framework is an approach to making our lives easier. Here are
some core’s features of .NET have mentioned:

Interoperability: Existing COM binaries can shuffle with
newer .NET binaries and vice versa.
In .NET 4.0, it has been further simplified with the “dynamic” keyword.

Support
programming languages: Various types of languages supported by .NET.

Common
runtime engine: This engine has a well-defined set of types
that each .NET-aware language understands.

Comprehensive
class library:This library provides a simple structure in
contrast with complexities of raw API calls and offers a common consistent
object model.

No more
COM drawbacks: .NET is simplified and doesn’t have COM complexities.

Simplified
deployment model:In .NET, there is no need to register binary unit into the system
registry. Furthermore, .NET allows
multiple versions of the same DLL to exist. The .NET platform has
nothing to do with COM (beyond the fact that both frameworks originated from
Microsoft). In fact, the only way .NET and COM types can interact with each
other is using the interoperability layer.

“In July 2009 Microsoft applied C#
and CLI under the Community Promise to the ECMA specs” (Galli, 2009).
Therefore, with no fear of patent lawsuit everyone is able to safely implement their
own standards based on CLI.

CLI (Common Language Infrastructure) and CLR

The CLI is an open
specification that describes the executable codeand runtime environment. It developed
by Microsoft and standardized by ISO and ECMA (European Computer Manufacturers
Association). It forms the core of the Microsoft .NET and other CLI implementations.
These specifications define an environment that allows several high-level
languages to be used on various types of computer platforms. The CLI
specification describes these aspects:

Common Type
System (CTS)

Common
Language Specification (CLS)

Base Class
Library (BCL)

Common
Intermediate Language (CIL)

Virtual
Execution System (VES)

Metadata

The Common Language
Runtime(CLR) is Microsoft's implementation of the
CLI standard and is responsible for managing the execution of .NET programs.
The CLR provides services including memory
management and garbage
collection,type safety,
and exception handling.
All programs by any language which has written for the .NET framework are
executed by the CLR and it is common to all versions of the .NET. Note that the
term CLR is not technically a generic term that is part of the CLI. Indeed, CLR
is the Microsoft specific runtime implementation for .NET platform. Some CLI implementations
are as followed:

Compiler

Description

Microsoft .NET Compiler

Premier compiler which limited to
run on the Windows.

Microsoft Silverlight

CLI Cross-platform implementation
that runs on both the Windows family and the Macintosh.

Microsoft Compact Framework

Light-weight implementation of the
.NET Framework designed to run on PDAs and phones.

Microsoft XNA

Implementation for Xbox and Windows
game developers.

Mono Project

Open source implementation designed
to provide Windows, Linux, and Unix compatible version of the CLI.

DotGNU

Focused on platform-portable
applications that can run both the .NET and the DotGNU. Supports GNU/Linux
BSD, Cygwin/Mingw32, Mac OS X, Solaris, AIX, and PARISC.

Rotor

Also known as the Shared Source CLI.
It’s CLI implementation that Microsoft developed to run on Windows, Mac OS X,
and FreeBSD for educational purposes.

CTS (Common Type System)

It defines the structure of
types (like their memory usage) and their behaviorsin external
boundaries of a language. The main CTS purpose is to achieve languages interoperability. CTS types are
broken down into two categories:

Valuesare bit patternsused to
represent basic types like integers
and characters. They also represent complex data like structures. The “separate
type designation” refers to the type
definition and it provides the meaning of each bit within the
value and the supported value operations. Each “value type” is related
to a “separate type designation” which has not stored within the bits.

Objectshave
identity that makes each instance
unique. Furthermore, objects have slots that can store other types (either values or
object references). Unlike values, changing the contents of a slot does not change
the identity of the object.

CTS Data Type

VB .NET Keyword

C# Keyword

C++/CLI Keyword

System.Byte

Byte

byte

unsigned char

System.SByte

SByte

sbyte

unsigned char

System.Int16

Short

short

short

System.Int32

Integer

int

int or long

System.Int64

Long

long

__int64

System.UInt16

UShort

ushort

unsigned short

System.UInt32

UInteger

uint

unsigned int or unsigned long

System.UInt64

ULong

ulong

unsigned __int64

System.Single

Single

float

float

System.Double

Double

double

double

System.Object

Object

object

object^

System.Char

Char

char

wchar_t

System.String

String

string

String^

System.Decimal

Decimal

decimal

Decimal

System.Boolean

Boolean

bool

bool

CLS (Common Language Specification)

Technically, CLS is a set of rules which define a subset of the
CTS. Its focus is library
implementations. It provides standards for writing libraries
that are accessible from the majority of source languages; even the source
languages are not CTS-compliant. It is intended to allow CLI languages to
provide facilities to create interoperable libraries; so it has called Common
Language Specification. CLS doesn’t deal with types that are not placed externally
to the assembly. In the other words, CLS rules apply only to those parts of a
type that are exposed outside the
defining assembly.

As an examples, CLS describes how a given language must
represent text strings, how enumerations should be represented internally, the
base type used for storage, and how to define static members.

Note that it is possible to have the compiler issue a
warning when you create an API that is not CLS compliant. To accomplish this,
use the assembly attribute “System.CLSCompliant” and specify a value of true
for the parameter.

BCL (Base Class Library) and FCL

BCL is a core
set of CLI class libraries that programs may utilize and it is
available for all CLI languages. This library collection provides fundamental types
and APIs which allows the programs to interact with the system runtime and OS functions
in a common approach. There is a Microsoft-specific library which is calling
the Framework Class Library(FCL)
that adds some features to BCL. It includes support for rich Client UI, web UI, database access, distributed communication,
and other libraries. The following table shows a list of standardize and non-standardized
namespaces are as following:

Standardized
namespaces:

System

System.Collections

System.Diagnostics

System.Globalization

System.IO

System.Net

System.Reflection

System.Runtime

System.Security

System.Text

System.Threading

System.Xml

System.Diagnostics.CodeAnalysis

System.Diagnostics.Contracts

System.Diagnostics.Eventing

System.Diagnostics.PerformanceData

System.Diagnostics.SymbolStore

Non-standardized
namespaces:

System.CodeDom

System.ComponentModel

System.Configuration

System.Data

System.Deployment

System.DirectoryServices

System.Drawing

System.EnterpriseServices

System.Linq

System.Linq.Expressions

System.Management

System.Media

System.Messaging

System.Resources

System.ServiceProcess

System.Timers

System.Transactions

System.Web

System.Windows.Forms

CIL (Common Intermediate Language) and IL

Old programming languages like C++ generate instructions (Mostly
called machine codes) that a processor can interpret directly. In contrast,
modern platforms Like Java and CLI compiler generate instructions in CIL language (In Java, BYTECODE).
.NET codes are compiled into IL(Microsoft
CIL implementation; also called MSIL), and IL is what the CLI processes. In
essence, IL is the CLI’s assembly languageand in
fact, it looks similar to assembly. It’s called IL (Intermediate Language)
because it acts as intermediate step between.NET language codes and a specific
platform. During execution time, the IL converts to machine code which current running
processor can understand. Different processors can understand different types
of machine codes instructions. However, this conversion to machine code is
still not adequate for code execution.

Languages that compile to the CIL are source languages and
each has a custom compiler that converts the source language to the CIL. Once codes
compiled to the CIL, the origin source language doesn't matter. This powerful
feature enables the development of libraries by different development groups,
without concern for the language choice of a particular group. Thus, the CIL
enables programming language
interoperabilityas well as platform portability.

VES (Virtual Execution System) or Runtime

VES(Virtual Execution System) or Runtime
is an agent which .NET Languages compilation is dependent to it. The Runtime is
able to understand CIL statements and compile them to machine code. This agent
is responsible for .NET programs execution
management andprovides
additional services(Garbage Collection, OS Security, Code Security…).
Most CLI implementations prefer CIL “execution-time compilation”. As a
result, they compile CIL codes
to machine code in run-time.
Nonetheless the time which compilation
must occur hasn't specified by the CLI. In fact, the CLI even allows
the CIL to be interpreted
rather than compiled (Similar
to scripting languages) or even get compiled to machine code immediately
instead of translated to CIL. Maintaining the control of the program, this
agent (VES) keeps running even after compilation of the CIL code to machine
code.

Managed code
is the code that executes under the agent control. Managed execution is the process of executing under
control of the “Runtime” (VES). In fact, memory for the data is automatically
allocated and de-allocated by the runtime. This process generally called
“Garbage Collection” and occurs by VES.

NGEN (Native Image Generator)

There is a .NET tool called NGEN which
allows compilation to machine codebefore running the program. It
can be considered as pre-execution time compilation (like C++) and needs to
take place on the computer on which the program will be executing. It is because
it will evaluate the machine characteristics (processor, memory,
platform, and so on) in
order to generate more efficient code. Its advantage is that it can reduce the
need for the jitter to run at startup and by this, it reduce the startup time.
However, it causes the compiled output to become dependent to the machine which it runs.

JIT (Just-In-Time) Compiler

JIT Compiler is a component inside the
“runtime” which performs compilation. JITTING can occur when the program is
installed or executed. The CLI is not an interpreter. Unlike interpreters, it doesn't re-translate the IL code each time it executes. Generally, interpreters aren’t efficient run-time
platforms. The process of compiling IL code into machine code takes
some time, but for each part of a program, it generally means only one-time compile
per process. Once the code is compiled, the CLI holds it and executes
the compiled version the next time it’s needed. It is just as quickly
as traditionally compiled code.

Since JIT compilation phase adds some complexity, it has initial run time performance reduction.
In fact, by putting the benefits of a JIT compiling structure and the CLI into
account, the time penalty of JIT compiling can be ignored. Managed applications
which have made by CLI are more
efficient than native compiled
applicationsbecause of the following:

IL code can consume less memory: Their working set is normally smaller than
native applications. Working set is the number
of memory pages applications consume. Keep in mind that to measure the
required work time for doing a job, the time for management structures, assembly metadata, and other constructs must calculated
which has done automatically by CLI. Thus, if you spend same amount of time for
doing a job which has same features, the amount of required work of native
applications will be much more than managed applications. However, for very
small applications, managed code along with the CLI can consume more memory
than the native one.

Only executed code is getting compiled:IL code is generally more compactthan
machine code. In fact, minimizing the compiled code reduces the memory footprint of the application.

JIT-compiled code is highly optimized:Code of
compiled native applications is optimized based on generalizations like the
typical computer system topology. In contrast, JIT compiled code is optimized based
on the current platform which it runs. Therefore, it is very specific optimization
and often generates far more performant code than statically compiled native
applications.

CLI may perform run time optimizations: In native
applications, you define the optimizations at compile time. But, because
compilation occurs at run time in the CLI, it can apply optimizations at any
time. For code that it getting called frequently, it could recompile with more
optimizations so it executes faster. The CLI efficiency can be different depending
on how many CPUs are on the target platform or even what architecture family
the CPUs belong to. In contrast, for native applications, you have to do more
manual work at both run time or compile time.

CLI intelligent compilation control: If the CLI
determines that some parts of code are placed in different locations bit they
call each other frequently, it has the liberty to move them in memory so that
they will be placed within the same group of memory pages and thus, it
minimizes the number of page faults and increasing the required cache when runs
application. In fact, in the native application case optimization is based on
guesses and assumptions whereas in the CLI case, the optimizations are based on
real data for the exact platform.

Assemblies

According to CLI specification, assembly is the CIL output after code’s
compilation. Assemblies can be library
assemblies (DLL – Class Libraries) or process assemblies (EXE - Executables). An assembly can
reference other assemblies and files such as resource files that have been
localized. This is an important specification modern programming platforms have,
because it significantly improves maintainability and allows a single component
to be shared across multiple programs.

An assembly can consist of one or more files. Code files are
called modules. Although
Visual Studio does not support using different languages in one assembly,
technically an assembly can contain more than one code module which has used
several different languages.

Assemblies form the logical construct of a component or unit
of deployment. Although an assembly can include multiple files, there is only one version number for the
entire group of files and it is placed in the main assembly manifest. If you
change any of the referenced files without updating the assembly manifest, you
will break the manifest and the assembly’s validity. Microsoft has provided “ILMerge.exe” utility
for combining multiple modules and their manifests into a single file assembly.

Assemblies can consist of multiple files. These files can include
compiled modules, resources, and any other components listed in the assembly
manifest. The assembly manifest is typically included in the main assembly
module and contains essential identification information, including which
pieces belong to the assembly. By using this information, the assembly loader
can determine, among other things, if an assembly is incomplete or has been
tampered with.

Assemblies are either strongly named or not strongly named. A
strongly named assembly has a hash code built into its manifest that the loader
can use to test the integrity of the assembly to ensure it has not been modified.
Assemblies can also be digitally signed in order to identify their producer.

All header information about a library and its dependencies
is in a portion of the metadata known as the manifest. Assembly manifest is a text file which
contains assembly’s metadata. It describes the relationship and dependencies
of the assembly’s components and the types it defines and imports. It also
expresses versioning information,
scope information and security permissions required
for it. It can be considered as assembly’s header. The manifest information
embedded within an assembly can be viewed using IL Disassembler (ILDASM.exe). The
manifest includes a reference to all the files an assembly depends on. As a
result, it can be used to determine an assembly’s dependencies.

During execution of the assembly, the runtime needs to
examine only the manifest to determine what files it requires. Unlike Microsoft’s
COM files of the past, CLI assemblies rarely require any type of registration.
Instead, it is possible to deploy applications by copying all the files that a
program requires into a particular directory, and then executing it. Because of
this, CLI applications deployment often referred to “xcopy” for its easy
deployment process.

Visual Studio .NET doesn't support integrated tools for
building multi-module assemblies,
and when they use such assemblies, IntelliSense does not fully function. Multi-module
assemblies not only facilitate breaking a program into components, but it also allows
the multiple source languages development.
Figure below illustrated a “Multiple Assembly”:

Metadata

It refers to types and files included (embedded) in a
program. Metadata attachment to the assembly files happens during execution the
IL instructions. It also describes all classes and their members
that are defined within it
or will call from outside of assembly.
A method’s metadata contains its description, including the class and its assembly, the return type and all of its parameters.

When the run-time executes IL it will check to make sure
that the metadata of the called method is the same as the metadata that is
stored in the calling method. This ensures that a method can only be called
with exactly the right number of parameters and exactly the right parameter
types.

Metadata provides a mechanism for the runtime to handle a
mixture of native and managed code execution. Also, it increases code and
execution robustness because it makes it easier to migrate from one library
version to another and it replaces compile-time-defined binding with load-time
implementation.

The metadata also contains custom attributes that may change
the code structure. Attributes provide additional metadata about CIL
instructions of the program at execution time. Metadata is available at
execution time by a mechanism known as reflection.

Garbage Collection

It is the process of automatically
de-allocating memory based on the program’s needs. This is a
significant programming problem for languages because without the garbage
collector, programmers must remember to always free any memory allocations they
make. Forgetting to do so, or doing so repeatedly for the same memory
allocation, results memory leaks
or corruption into the
program.

Garbage collection is obviously a core function of the
runtime. Its purpose is to restore memory consumed by objects that are no
longer referenced. The emphasis in this statement lies with memory and
references. The garbage collector is only responsible for restoring memory; it
does not handle other resources such as database
connections, handles
(files, windows, and so on), network
ports, and hardware devices
such as serial ports. Also, the garbage collector determines what to clean up
based on whether any references
remain. This means that the garbage collector works with reference
objects and restores heap’s memory
only. In addition, maintaining a reference to an object will delay the garbage
collector from reusing the memory consumed by the object.

Points of Interest

As far as I realized, it's not easy to find a simple succinct explanation about the .Net architecture in the Web. I believe it is useful for every .Net developer (regardless of their level of experts) to know the fundamental structure of .Net framework. In addition, it is good to know some features about .Net in order to understand the advantages of .Net as a platform. I, personally learned many new features and specifications of .Net by doing this research. I have to emphasize that this article which I compiled is mostly a research based article. It based on my experience and the resources which I looked in order to elicit comprehensible easy-to-understand information for each part. I'll try to add more information when I learned.

Share

About the Author

I am a software developer/analyst with professional experience working on a variety of software projects from conception to delivery. My focus in field of expertise is design and implementation of healthcare information systems. Currently, I am a graduate student in health informatics at University of Texas Health Science Center at Houston.
I'm familiar with a wide range of technologies; most notably and preferably Microsoft.NET and Microsoft SQL Server. I also follow the latest industry trends such as Cloud Computing with great interest. Particularly, I am passionate and proficient in C# as a programming language and generally .NET platform and enjoy developing applications for different types of platform and device. I also code in Python, Java, Jython, and Haskell for my employer.

Comments and Discussions

You need to clean up the English, a lot of the sentences just plain don't make sense. eg. "Java’s is platform independence language and as a language, it has many revisions for C unpleasant syntactical pieces."
It's a potentially great article, but you need to proof-read it to that it's clear what it is you're trying to say.

True, I tried to write a succinct useful text about .Net architecture. Since I've been a senior .Net database developer, I didn't know that much about .Net architecture before. I decided to collect as much useful information as I could in a short period of time. I will try to improve the language soon. I will elaborate the concepts in the future revisions as well.
Anyhow, thanks for your comment. In fact, I've been waiting for someone to say something like that.

I do feel it's a potentially great article. All the headings suggest you have the foundations or skeleton of a good overview of the architecture. But, for me, the text is a little bit too 'note format' - if you flesh it out a little I think you have a winner.
Certainly don't give up on it, I'm looking forward to the next revision.