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
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 language and it doesn't provide the object-oriented approach. Combination of many global functions and
data types defined by the Windows API to a robust complicated language; made many
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 difficult and prone to error.<o:p />
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 inheritance and has no support for parameterized object construction.
Moreover, VB6 doesn't provide the ability to build multithreaded applications unless
you call low-level APIs which are complex
and dangerous.<o:p />
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). <o:p />
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 integration because 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-transparent nature 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.<o:p />
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 platform for 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.
programming languages: Various types of languages supported by .NET.
runtime engine: This engine has a well-defined set of types
that each .NET-aware language understands.
language integration: .NET supports cross-language inheritance, exception handling, and debugging of code.
class library: This library provides a simple structure in
contrast with complexities of raw API calls and offers a common consistent
- No more
COM drawbacks: .NET is simplified and doesn’t have COM complexities.
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” <w:sdt citation="t" id="-1355651325">(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 code and 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
Language Specification (CLS)
- Base Class
Intermediate Language (CIL)
Execution System (VES)
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:
Microsoft .NET Compiler<o:p />
Premier compiler which limited to
run on the Windows.<o:p />
Microsoft Silverlight<o:p />
CLI Cross-platform implementation
that runs on both the Windows family and the Macintosh.<o:p />
Microsoft Compact Framework<o:p />
Light-weight implementation of the
.NET Framework designed to run on PDAs and phones.<o:p />
Microsoft XNA<o:p />
Implementation for Xbox and Windows
game developers. <o:p />
Mono Project<o:p />
Open source implementation designed
to provide Windows, Linux, and Unix compatible version of the CLI.<o:p />
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.<o:p />
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.<o:p>
CTS (Common Type System)
It defines the structure of
types (like their memory usage) and their behaviors in external
boundaries of a language. The main CTS purpose is to achieve languages interoperability. CTS types are
broken down into two categories:
- Values are bit patterns used 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.
- Objects have
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<o:p>
VB .NET Keyword<o:p />
C# Keyword<o:p />
C++/CLI Keyword<o:p />
unsigned char<o:p />
unsigned char<o:p />
int or long<o:p />
unsigned short<o:p />
unsigned int or unsigned long<o:p />
unsigned __int64<o:p />
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.<o:p />
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. <o:p />
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:
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 language and 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.<o:p />
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
interoperability as 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 and provides
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
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.<o:p />
NGEN (Native Image Generator)
There is a .NET tool called NGEN which
allows compilation to machine code before 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
applications because 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 compact than
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
- 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.
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. <o:p />
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.<o:p />
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. <o:p />
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. <o:p />
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
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”:
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
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
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.
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. <o:p />
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
(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.
- Galli, P., 2009. The ECMA C# and CLI Standards. [Online] Available at:
http://blogs.technet.com/b/port25/archive/2009/07/06/the-ecma-c-and-cli-standards.aspx [Accessed 12 7 2012].
- Griffiths, I., Adams, M. & Liberty, J., 2010.
Programming C# 4.0. 6th ed. Sebastopol, CA: O’Reilly.
- MSDN, 2012. Assembly Manifest. [Online] Available at:
http://msdn.microsoft.com/en-us/library/1w45z383.aspx [Accessed 2 9 2012].
- Nagel, C. et al., 2010. Professional C# 4 and .NET 4.
Indianapolis, Indiana: Wiley.
- Nash, T., 2010. Accelerated C# 2010. 1st ed. New York:
- Troelsen, A., 2010. Pro C# 2010 and the .NET 4 Platform. 5th
ed. New York: Apress.
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.
1.0 - 9/29/2012: The first publish of the article.