8 Chapter 1 • Introducing the Microsoft .NET Platform
in use, these objects will always have a reference count greater than zero, so unless
they are implicitly deconstructed, their memory may never be recovered.
For a C or C++ programmer—accustomed to ensuring that objects are
properly destroyed, essentially managing memory on their own—this sounds per-
fectly normal, and a good reason for not trusting anyone else to take care of
managing resources. However, in the .NET environment, Microsoft is striving to
make developing software easier. Later in this chapter, we cover a how .NET
garbage collection works, and the improvements that have been made over strict
reference counting or manual memory management approaches.
Versioning Support
Anyone who doesn’t understand the phrase “DLL Hell” hasn’t been developing
(or at least supporting) software for Windows very long. For the uninitiated,
you’ll find yourself in DLL Hell someday when a customer installs a software
package that uses one of the same DLLs as your application. However, your appli-
cation used version 1.0 of this DLL, and the new software replaces it with version
1.1.We developers all always make sure everything is 100% backwards-compat-
ible, right? The new DLL makes your application exhibit some strange problem
or perhaps just stop working altogether.After a lot of investigation, you figure out
what the offending DLL is and have the customer replace the new one with the
version that works with your software. Now their new software doesn’t work…
welcome to DLL Hell. Many developers resort to simply installing every DLL
their application requires in the application directory so that it will be found first
when the application loads the libraries.This defeats the purpose of shared
libraries, but it is one way around the problem.
COM was going to change this; one of its primary tenants was that you never
changed a methods interface you simply add new methods. Unfortunately, software
developers are frequently perfectionists, and leaving a “broken” function alone just
chafes some people. Problem is, changing a components interface once it’s in use
can have adverse affects on the client software that expected the old behavior.
Because COM objects are loaded using information in the Registry, simply placing
adopted beyond its own domain.
Easy Deployment
Today, developing installations for Windows-based applications can be incredibly
difficult, to the point that most companies use third party tools for developing
their installation programs, and even then it’s not pleasant.There are usually a
large number of files to be installed in several directories, various Registry set-
tings, installation of required COM components, and shortcuts that need to be
created, and so on. Completely uninstalling an application is nearly impossible,
most leave bits and pieces of themselves around even if they provide an uninstall
feature.With the release of Windows 2000, Microsoft introduced a new installa-
tion engine that helps with some of these issues, but it is still possible that the
author of a Microsoft Installer Package may fail to do everything correctly. Even
with those third party tools specifically designed to make developing installation
programs easier, it is still frequently a monumental task to correctly install a
retrievial application.
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 9
10 Chapter 1 • Introducing the Microsoft .NET Platform
The .NET design team must have felt the same way about this problem,
because .NET plans to do away with these issues for good. .NET components
are not referenced in the Registry, thanks to the use of metadata and reflection,
components are self describing. In fact, installing many .NET applications will
require no more than copying their files to a directory, and uninstalling an appli-
cation will be as easy as deleting those files.
Distributed Architecture
Today’s distributed applications are much different than those we will see in the
future. Microsoft certainly believes this; they say they are betting the company on
the concept of distributed Web services.
www.syngress.com
Using the Visual Studio.NET Setup Tools
remote sites, combining it with information from their user database and merging
it all into an integrated product that is delivered to the user via their browser.
As useful as these types of applications are, they are all very complex to
develop and maintain. Each provider of information has developed different
interfaces to access data and processes on their servers.This redundant develop-
ment is grossly inefficient and for the most part fairly boring, so there has been a
great deal of activity around three standards to streamline the process: XML,
SOAP, and UDDI.As we discussed earlier, these are used in .NET and also in
competing, less well known initiatives from IBM and Sun.
Interoperability with Unmanaged Code
As you can probably guess, unmanaged code is code that isn’t managed by the
.NET Common Language Runtime. However, this code is still run by the CLR,
it just doesn’t get the advantages that it offers, such as the Common Type System
and Automatic Memory Management.You will probably end up using unman-
aged code in a couple of different situations:
■
Calling DLL functions There is a lot of functionality locked inside
DLLs today. Not every company is going to rush to deliver a .NET
component version of their products, so if you need to interface with
them, you’ll be calling unmanaged code.
■
Using COM components This is likely to be for pretty much the
same reasons you might be required to call DLL functions.
■
Calling .NET services from COM components Although this
sounds a little odd, it is possible.A COM client can be made to call a
.NET component as though it was a COM server.
Here’s a little more information on the COM interoperability issue. Microsoft
didn’t want to force companies to abandon their existing COM components;
especially because many of Microsoft’s own products are COM-based today.
verified. .NET security crosses process boundaries and even machine boundaries to
prevent access to sensitive data or resources in a distributed application environ-
ment.The following are some of the basic elements of the .NET security system:
■
Evidence-based security is a new concept introduced by the
.NET Framework. An assembly contains several important pieces of
information that can be used to decide what level of access to grant the
component. Some of the information used includes what site the com-
ponent was downloaded from, what zone that site was in, (Internet,
intranet, local machine, and so on) and the strong name of the assembly.
The strong name refers to an encrypted identifier that uniquely defines
the assembly and ensures that it has not been tampered with.
■
The .NET Common Language Runtime further provides secu-
rity using a Policy-Driven Trust Model Using Code Evidence.
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 12
Introducing the Microsoft .NET Platform • Chapter 1 13
It sounds worse than it really is. Essentially this is a system of security
policies that can be set by an administrator to allow certain levels of
access based on the component’s assembly information.The policies are
set at three levels: the enterprise, the individual machine, and the user.
■
Calling .NET Framework methods from the Base Class Library
get the benefits of built in security. That is, the developer doesn’t
have to make explicit security calls to access system resources. However,
if your components expose interfaces to protected resources, you will be
expected to take the appropriate security measures.
■
Role-based security plays a part in the .NET security scheme.
167_C#_01.qxd 12/3/01 5:42 PM Page 13
14 Chapter 1 • Introducing the Microsoft .NET Platform
Performance and Scalability
Let’s face it—there is no magic bullet that will allow a poorly designed applica-
tion to scale well.What the .NET Framework is giving you are tools to make it
easier to design better performing software. One big gain for Web development
will come from ASP.NET’s improved support for keeping code, data, and presen-
tation separate. .NET offers features for transaction handling and component
pooling, but makes them easier to use than they were in previous incarnations, so
more development will be likely to take advantage of them.The .NET Base Class
Library has an enormous set of functionality, which means that you will have to
write less basic code and spend more time refining the features and performance
of your applications.
New versions of Microsoft software christened with the .NET emblem offer
improved performance over earlier versions. SQL Server.NET offers quite an
enhancement over earlier versions of the database engine, and other server prod-
ucts offer enhanced scalability as well.When you redesign an application around
the .NET Framework, take advantage of the latest advances all around and see
what the results are.
Components of the .NET Architecture
As we mentioned earlier, there is a lot to the .NET Framework. In this section,
we identify the individual components and describe their features and how they
fit into the overall picture.
.NET Runtime
The heart of the .NET Framework is the CLR. Similar in concept to the Java
Virtual Machine, it is a runtime environment that executes MSIL code. Unlike
the Java environment, which is the concept of one language for all purposes, the
.NET platform supports multiple programming languages through the use of the
Common Language Specification, which defines the output required of com-
pilers that want to target the CLR.
.NET Base Class Library (BCL)
If I could have bought a library that offered everything the .NET Base Class
Library offers when I started programming, a year’s salary would have seemed
reasonable—there really is that much to it.Almost everything in the .NET envi-
ronment is contained within the BCL. Let’s look at a “Hello World” example:
using System;
class Hello
{
public static void Main()
{
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 15
16 Chapter 1 • Introducing the Microsoft .NET Platform
Console.WriteLine("Hello World");
}
}
The only function contained in this simple program is a call to the WriteLine
method of the Console class.What is really unique about the .NET environment
is that .NET languages don’t have to implement even the most basic functions;
they are available in the BCL. Because all .NET languages share the same
common set of libraries, the code being executed by your C# program is the
same code being executed by a program written in another language.This means
that all languages that target the .NET environment essentially share the same
capabilities, except they have different syntax.
Some people will wonder why we even have different languages if they all
have the same capabilities.A few reasons immediately spring to mind:
■
Programmers don’t like change.
■
Programmers usually have a favorite language.
and a declaration, including names and types, for all of its members (methods,
fields, properties, and events). For every method implemented by the component,
the metadata contains information that the loader uses to locate the method
body. It is also possible (but not required) for the creator of a class type to asso-
ciate help text and comments with a method or parameter in the metadata, sim-
ilar to the way that information can be associated with a component using
information within the IDL in the COM world.
Besides the low-level information described in this section, a component also
includes information regarding its version and any culture information specific to
the component.The culture information can be queried at runtime and used in
developing localized applications. Look at the System.Reflection.AssemblyName class
as a place to get started, and check out the CultureInfo class to see how extensive
the culture support of .NET components can be.You can also use reflection to
determine a components version, which might be useful if your application is
dynamically loading components and needs to make adjustments for different
versions.
Assemblies and Modules
.NET applications are deployed as assemblies, which can be a single executable or
a collection of components.When you create a .NET application, you are actu-
ally creating an assembly, which contains a manifest that describes the assembly.
This manifest data contains the assembly name, its versioning information, any
assemblies referenced by this assembly and their versions, a listing of types in the
assembly, security permissions, its product information (company, trademark, and
so on), and any custom attribute.
An assembly that is shared between multiple applications also has a shared
name (also known as a strong name).This is a key pair containing a globally unique
name (think GUID from COM) as well as an encrypted digital signature to pre-
vent tampering.This information is optional and may not be in a component’s
manifest if it was not intended as a shared component.
www.syngress.com
script, and code written in any of the .NET supported languages com-
plete with integrated call stacks offering a total solution for end-to-end
development.
Debugging…
167_C#_01.qxd 12/3/01 5:42 PM Page 18
Introducing the Microsoft .NET Platform • Chapter 1 19
previous version of an assembly that may be needed by another application.You
read that right, the .NET Framework is making a solid effort to banish DLL Hell.
Just to clarify what this means, the assembly cache can contain multiple ver-
sions of a component, as an example, we’ll say we’ve installed versions 1.0 and 1.1
of MyComponent.dll on a system. If an application was built and tested using
Version 1.0 of MyComponent.dll, the CLR will see this when it reads the appli-
cation’s metadata and will load Version 1.0 of MyComponent.dll, even though a
later version of the assembly exists in the cache.The application will continue to
function normally because the code that it is executing is the same code that it
was built and tested with.Thanks to this feature, you also don’t have to maintain
compatibility with earlier versions of your components.This feature alone is
enough to make the .NET architecture great.
Reflection
Reflection is the means by which .NET applications can access an assembly’s meta-
data information and discover its methods and data types at runtime.You can also
dynamically invoke methods and use type information through late binding
through the Reflection API.
The System.Type class is the core of the reflection system. System.Type is an
abstract class that is used to represent a Common Type System type. It includes
methods that allow you to determine the type’s name, what module it is con-
tained in, and its namespace, as well as if it is a value or reference type.
For example, using the System.Reflection.Assembly class you can retrieve all of
the types in an assembly, and all of the modules contained in the assembly.To
invoke a method of a class loaded at runtime, you would use a combination of
gramming time away from developing new code while you track down memory
leaks.A day spent hunting for an elusive memory problem usually isn’t a produc-
tive day.
.NET hopes to do away with all of that within the managed environment
with the garbage collection system. Garbage collection runs when your applica-
tion is apparently out of free memory, or when it is implicitly called but its exact
time of execution cannot be determined. Let’s examine how the system works.
When your application requests more memory, and the memory allocator
reports that there is no more memory on the managed heap, garbage collection is
called.The garbage collector starts by assuming everything in memory is trash
that can be freed. It then walks though your application’s memory, building a
graph of all memory that is currently referenced by the application. Once it has a
complete graph, it compacts the heap by moving all the memory that is gen-
uinely in use together at the start of the free memory heap.After this is complete,
it moves the pointer that the memory allocator uses to determine where to start
allocating memory from the top of this new heap. It also updates all of your
application’s references to point to their new locations in memory.This approach
is commonly called a mark and sweep implementation.
The exception to this is with individual objects over 20,000 bytes.Very large
objects are allocated from a different heap, and when this heap is garbage col-
lected, they are not moved, because moving memory in this size chunks would
have an adverse effect on application performance.
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 20
Introducing the Microsoft .NET Platform • Chapter 1 21
As you can see, garbage collection involves a lot of work, and it does take
some time.A number of performance optimizations involved in the .NET
garbage collection mechanism make it much more than the simple description
given here.
Normally you will just let the CLR take care of running garbage collection
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4
.ver 1:0:2411:0
}
.assembly Hello
{
.custom instance void [mscorlib]System.Reflection.
AssemblyKeyNameAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyKeyFileAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyDelaySignAttribute::.ctor(bool) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyProductAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.
AssemblyTitleAttribute::.ctor(string) = ( 01 00 00 00 00 )
// The following custom attribute is added automatically, do not
// uncomment
// .custom instance void
// [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,
installs with VS .NET, you will see that it is bound to mscoree.dll for this func-
tion, but you won’t see any of the DLLs containing the .NET Base Class Library
Functions.This is because those functions are invoked through the CLR, not
through the normal Windows operating system functions. Figure 1.2 illustrates
the process by which your application’s source code is eventually executed as
native code.
1. When the application is executed, it first behaves just like a normal
Win32 application, loading any required libraries, including mscoree.dll,
which exports the _CorExeMain function.
2. The loader then jumps to the EXE’s entry point. Because the Windows
operating system itself cannot execute the MSIL code, the C# compiler
placed the _CorExeMain function at the entry point.
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 23
24 Chapter 1 • Introducing the Microsoft .NET Platform
3. When the _CorExeMain function is invoked, it begins the execution of
the MSIL code.
4. The CLR compiles the MSIL code into the native machine format as it
processes the MSIL code by using a JIT compiler.The JIT compiles
code as it is executed, it does not process the entire application before
beginning execution. Once a given function is compiled, the resulting
machine code is cached so that it does not have to be recompiled at a
later point.
5. The native code is then executed by the system.
The Pursuit of Standardization
Microsoft is actively pursuing a process whereby the Common Language
Infrastructure and C# Programming Language can be standardized so that any
www.syngress.com
Figure 1.2 Code Cycle Diagram
Application source code is written.
manner of smart devices, computers, and services work together to provide a
richer user experience.The .NET platform is Microsoft’s vision of how the
developers of this new breed of software will approach the challenges this change
will provide.
If some of the .NET concepts sound familiar, there’s a good reason:The
.NET platform is the next generation of what was called Windows DNA.
Although Windows DNA did offer some of the building blocks for creating
robust, scalable, distributed systems, it generally had little substance in and of
itself, where .NET actually has an integrated, comprehensive design and well
conceived, usable tools.
The components at the heart of the .NET platform are the Common
Language Runtime, the Base Class Library, and the Common Language
Specification.The .NET Base Class Library exposes the features of the Common
Language Runtime in much the same way that the Windows API allows you to
utilize the features of the Windows operating system. However, it also provides
many higher-level features that facilitate code reuse.The Common Language
Specification gives language vendors and compiler developers the base requirements
for creating code that targets the .NET Common Language Runtime, making it
much easier to implement portions of your application using the language that’s
best suited for it.The .NET platform allows languages to be integrated with one
another by specifying the use of the Microsoft Intermediate Language (MSIL, or
just IL) as the output for all programming languages targeting the platform.This
intermediate language is CPU-independent, and much higher level than most
machine languages.
Automatic resource management is one of the most discussed features of the
.NET platform, and for good reason. Countless man-hours have been spent
chasing problems introduced by poor memory management.Thanks to the man-
aged heap memory allocator and automatic garbage collection, the developer is
now relieved of this tedious task and can concentrate on the problem to be
solved, rather than on housekeeping.When an allocated object is no longer
Developing software using .NET technology is a big change; the technology
has a lot of pieces to the puzzle and more than a few new ideas. Hopefully, we have
given you a solid introduction into the basics, and you now have a foundation
upon which to build your skills using the information found in the rest of the
book. If you want more detail on a particular feature of the platform, the MSDN
Web site contains a vast amount of reference material that covers the features of the
.NET platform at a much more technical level than we attempted here.
Solutions Fast Track
Introducing the .NET Platform
; Software is changing from a closed to a connected world, much like
personal computers themselves are.The .NET Framework is designed to
www.syngress.com
167_C#_01.qxd 12/3/01 5:42 PM Page 27