1.1 .NET Platform Fundamentals
At the core of
Microsoft's .NET platform initiative is a new set of
technologies known collectively as the .NET
Framework , which we'll refer to
commonly as the Framework. The Framework provides a platform for
simplified rapid development of both web-based and Windows-based
applications. The Framework has two primary components,
the
Common Language
Runtime (CLR) and the Framework
Class Library (FCL).As with many new technologies, there are a host of new terms and
acronyms to understand, so we'll introduce and
explain the most important ones in the Framework over the next
several sections.
1.1.1 The Common Language Runtime (CLR)
The CLR is the execution environment for code written for the .NET
Framework. The CLR manages the execution of .NET code, including
memory allocation and garbage collection (which helps avoid memory
leaks), security (including applying differing trust levels to code
from different sources), thread management, enforcing type-safety,
and many other tasks.The CLR works with every language available for the .NET Framework,
so there is no need to have a separate runtime for each language.
Code developed in a .NET language is compiled by the individual
language compiler
(such as the Visual Basic .NET compiler) into an
intermediate format called (appropriately enough)
Intermediate Language (IL). At
runtime, this IL code generated by the compiler is
just-in-time (JIT) compiled by the CLR
into native
code
for the processor type the CLR is running on. This compilation
provides the flexibility of being able to develop with multiple
languages and target multiple processor types while still retaining
the performance of native code at execution time.
|
1.1.2 The .NET Framework Class Library (FCL)
The FCL is a set of reusable object-oriented classes that provide
basic platform functionality, from the data access classes of
ADO.NET, to filesystem utility classes (including file, directory,
and stream classes), to networking classes that allow easy
implementation of DNS resolution, WHOIS lookups, and other
network-related functionality. Developers can use the base classes
directly or derive from these classes to provide customized
functionality.The FCL also contains all classes that make up ASP.NET. These include
classes that implement all of the functionality of the ASP intrinsic
objects, as well as classes that provide additional functionality,
from a rich engine for caching output and data to the ASP.NET Server
Control model. This functionality brings to ASP.NET the simplicity of
control-based development that has long been available to Visual
Basic developers.In addition to classes that support Web application development, the
FCL provides classes for developing console applications, Windows
applications, and Windows NT or Windows 2000 Services.
1.1.3 The Common Type System (CTS)
The CTS describes the set of types that are
supported by the CLR. This includes both value types, which include primitive
data types such as
Byte,
Int16,
Double, and
Boolean,
and reference types, which include
arrays,
classes, and the
Object
and String types.Value types are types that
store their values directly in memory and are accessed directly by
name, as shown in the following code fragment:
'VB.NET
Dim myFloat As Single
myFloat = 3.1415
// C#
float myFloat;
myFloat = 3.1415;
In addition to these built-in data types, value types also include
user-defined value types (types derived from the
System.ValueType class) as well as
enumerations.Reference types are types
that store a reference to the location of their values, rather than
storing the value directly. Frequently, the value is stored as part
of a defined class and is referenced through a class member on an
instance of the class, as shown here:
'VB.NET
'Define class
Class myFloatClass
Public myFloat As Single
End Class
'Create class instance and assign value
Dim myInstance As New myFloatClass( )
myInstance.myFloat = 3.1415
// C#
// Define class
class myFloatClass
{
float myFloat;
}
// Create class instance and assign value
myFloatClass myInstance = new myFloatClass( );
myFloatClass.myFloat = 3.1415;
Individual language compilers may implement types using their own
terminology. For example, while the .NET representation of a
32-bit
integer is referred to as Int32 , in Visual Basic
.NET it is referred to as Integer and in C# as
int . Internally,
however, both Visual Basic's Integer and
C#'s int are implemented as the .NET Int32 type.
1.1.3.1 Boxing and unboxing
Converting to and from value and reference types is accomplished
through a process called boxing and unboxing.
Boxing
refers to the implicit conversion of a value type, such as a C# int,
to a reference type (usually Object ). For this
conversion to take place, an instance of type Object is created and
the value type's value and type is copied into
itin this case, int.
Unboxing
refers to the explicit conversion of an Object type into a specific
value type. The code example shown here demonstrates boxing and
unboxing:
// C#
int myInt = 123; // declare an int and set its value to 123
object myObj = myInt; // value of myInt is boxed into myObject
int myOtherInt = (int)myObject; // unbox myObject into myOtherInt
1.1.4 The Common Language Infrastructure (CLI)
The CLI is a subset of the .NET
Framework that has been submitted for standardization through the
ECMA standards body. The CLI includes the functionality of the Common
Language Runtime, as well as specifications for the Common Type
System, type safety rules, Metadata, and Intermediate Language. It
also includes a subset of the Framework Class Library that includes a
Base Class Library (for built-in types and basic runtime
functionality), a Network Library (for simple networking services and
access to network ports), a Reflection Library (for examining types
and retrieving information about types at runtime), an XML Library
(for parsing XML), and Floating Point and Extended Array Libraries.Microsoft has also committed to providing what they refer to as a
"shared- source" implementation of
the CLI, which will be available for both the FreeBSD and Windows
operating systems. You can find out more about the shared-source CLI
implementation at http://msdn.microsoft.com/library/en-us/dndotnet/html/mssharsourcecli2.asp.There is also a group working on an open source implementation of the
CLI, based on the ECMA specifications, called Mono. You can find out
more about Mono at http://www.go-mono.org/.Information on the ECMA standardization process, including
documentation of the proposed standards, is available at http://msdn.microsoft.com/net/ecma/.
1.1.5 The Common Language Specification (CLS)
The CLS is a subset of the types
supported by the CLR, as well as a set of rules that language and
compiler designers must follow. The purpose of the CLS is to provide
robust interoperability between .NET languages, including the ability
to inherit classes written in one .NET language in any other .NET
language and cross-language debugging.The rules defined by the CLS apply only to publicly exposed features
of a class. For example, the internal implementation of a class can
use non-CLS-compliant types (such as the unsigned integer types), but
as long as only CLS-compliant members are exposed publicly, the class
can still take full advantage of the interoperability features
enabled by the CLS.
1.1.6 Classes
While not a term specific to the .NET platform, the term
class may be new to many ASP developers. A
class is essentially
the blueprint for an object. It contains the definition for how a
particular object will be instantiated at runtime, such as the
properties and methods that will be exposed publicly by the object
and any internal storage structures.Developers work with classes by creating
instances
of the class at runtime using the new keyword, as
shown here:
// Instantiate the .NET StreamReader class in C#
System.IO.StreamReader sr;
sr = new System.IO.StreamReader("C:\\Test.txt");
string Line;
while(sr.Peek( ) != -1)
{
Line = sr.ReadLine( );
Response.Write(Server.HtmlEncode(Line) + "<br/>");
}
We preface the name of the class, StreamReader,
with its namespace name, System.IO, to prevent
naming collisions with other classes in different assemblies that
might have the same name and to ensure that we get the
StreamReader class we expect.
We'll discuss namespaces and assemblies later in
this section.
1.1.7 Namespaces
Namespaces ,
a key part of the .NET Framework, provide scope to both preinstalled
framework classes and custom-developed classes. Namespaces are
declared for a given set of classes (types) by enclosing those
classes in one of the following declarations:
// C#
namespace myNamespace
{
class myClass
{
// class implementation code
}
}
' VB.NET
Namespace myNamespace
Class myCls
' class implementation code
End Class
End Namespace
Namespaces may also be nested, as shown here:
' VB.NET
Namespace myFirstNamespace
Public Class myCls
' class implementation code
End Class
Namespace mySecondNamespace
Public Class myCls
' class implementation code
End Class
Public Class myCls2
' class implementation code
End Class
End Namespace
End Namespace
This code is perfectly valid because we've declared
the second myCls in the nested namespace
mySecondNamespace. If we tried to declare two identically named
classes within the same namespace, we would get a compiler error
informing us that there was a naming conflict, because each class
name must be unique within its namespace. To use the classes we just
declared, we can do something like the following:
' VB.NET
Imports System
Imports myFirstNamespace
Imports myFirstNamespace.mySecondNamespace
Module namespaces_client_vb
Sub Main( )
Dim newClass As New myFirstNamespace.myCls
Dim newClass2 As New myCls2
Console.WriteLine("Object creation succeeded!")
End Sub
End Module
We use the Imports keyword in
Visual Basic .NET to enable the use of
member names from these namespaces without explicitly using the
namespace name. However, because we used the class name
myCls in both the myFirstNamespace and
mySecondNamespace namespaces, we need to use the fully qualified name
for this class, while we are able to instantiate
myCls2 with only the class name. We can just as
easily use these classes from C#, as shown here:
using System;
using myFirstNamespace;
using myFirstNamespace.mySecondNamespace;
class namespaces_client
{
public static void Main( )
{
myFirstNamespace.myCls newClass = new myFirstNamespace.myCls( );
myCls2 newClass2 = new myCls2( );
Console.WriteLine("Object creation succeeded!");
}
}
C# uses the using keyword for importing
namespaces. Notice that in both cases, in addition to importing the
namespaces we defined, we've also imported the
System namespace. This is what allows us to use the
Console class defined in the System namespace to
write to a console window without referring explicitly to
System.Console.Classes that are part of the .NET Framework are organized by
functionality into namespaces that make them easier to locate and
use. All
classes
that are a part of the .NET Framework begin with either
"System" or
"Microsoft." Examples include:
- System
Contains all the .NET primitive data types as well as utility classes
such as Console and Math that
are apt to be widely used in .NET applications.- System.Collections
Contains classes used to implement various kinds of collections in
.NET, including ArrayList,
Dictionary, and Hashtable.- System.Data
Contains classes used to access and manipulate data, as well as child
namespaces such as System.Data.SqlClient, which contain data access
classes specific to a particular data provider.- System.Web
Contains classes used to process web requests, as well as child
namespaces such as System.Web.UI, which contains such classes as the
Page class, the basis for all ASP.NET pages.
1.1.8 Assemblies
Also known as Managed DLLs,
assemblies
are the fundamental unit of deployment for the .NET platform. The
.NET Framework itself is made up of a number of assemblies, including
mscorlib.dll ,
among others. The assembly boundary is also where versioning and
security are applied.An assembly contains Intermediate
Language generated by a specific language compiler, an assembly
manifest (containing information about the assembly), type metadata,
and resources. We'll discuss IL, manifests, and
metadata later in this section.Assemblies can be either private, residing in the directory of the
client application from which they are used (or, in the case of
ASP.NET, in the / bin
subdirectory of the Web application), or shared. Shared assemblies
are stored in a common location called the Global
Assembly Cache (GAC).
Assemblies that are to be installed in the GAC must be strongly
named, which means that they must have a cryptographic key associated
with them. Strong naming can be accomplished either through Visual
Studio .NET, or you can use the sn.exe tool
supplied with the .NET Framework SDK to generate a key pair for
signing the assembly, and then use the al.exe
tool to create the signed assembly based on the generated key.
We'll demonstrate creating and sharing strongly
named assemblies in Chapter 6.Assemblies are self-describing, thanks to the manifest contained
within them. One advantage of their self-describing nature is that it
makes it possible for different versions of the same assembly to be
run side by side. Clients can then specify the version of the
assembly that they require, and the CLR will make sure that the
correct version of the assembly is loaded for that client at runtime.
1.1.9 Intermediate Language (IL)
IL, also known as MSIL (for Microsoft
Intermediate Language), is a processor-independent representation of
executable code. IL is similar in some ways to assembly code, but it
is not specific to a particular CPU; rather, it is specific to the
CLR. IL is generated by each of the language compilers that target
the CLR. As mentioned above, .NET assemblies contain IL that is to be
executed by the CLR.At runtime, the CLR just-in-time (JIT) compiles the IL to
native code, which is then executed. There is also a tool called
ngen.exe , which is
supplied with the .NET Framework SDK and allows you to precompile
assemblies to native code at install time and cache the precompiled
code to disk. However, while precompiling an assembly to native code
will improve the startup time of an assembly, the JIT process used by
the CLR performs optimizations that may allow JITed code to perform
better than precompiled code, the difference in performance will
depend on the code being executed, and how subject to these
optimizations it is.
1.1.10 Managed Execution
Managed
execution refers to code whose execution is
managed by the CLR. This execution includes memory management, access
security, cross-language integration for debugging and/or exception
handling, and many other features. Managed assemblies are required to
supply metadata that describes the types and members of the code
contained within the assembly. This information allows the CLR to
manage the execution of the code.
|
1.1.11 Manifests, Metadata, and Attributes
Metadata and
manifests are key
pieces of the managed execution world. Manifests
are the portion of an assembly that contains descriptive information
about the types contained in the assembly, the members exposed by the
assembly, and the resources required by the assembly. The manifest
contains metadata , which, simply put, is data
that describes the assembly. Some metadata is generated by the
language compiler at compile time. The developer may add other
metadata at design time through the use of attributes.
Attributes are declarations added to code that
describe some aspect of the code or modify the
code's behavior at runtime.Attributes are
stored with an assembly as metadata and are used for many purposes in
the .NET Frameworkfrom the <webMethod(
)> attribute used to turn a normal method into a web
service to attributes used to define how custom controls interact
with the Visual Studio .NET environment.

