Introducing .NET

.NET Framework

Secondly, the entire architecture has been created to make it as easy to develop Internet applications as it is to develop for the desktop environment.

.NET actually "wraps" the operating system, insulating software developed with .NET from most operating system specifics such as file handling and memory allocation. This prepares for a possible future in which the software developed for .NET is portable to a wide variety of hardware and operating system foundations. (Beta one of Visual Studio.NET supports all versions of Windows 2000 plus Windows NT4, Windows 9x, and Windows Millennium Edition.)

A Common Substrate for all Development

The major components of the .NET framework are shown in the following diagram:

The framework starts all the way down at the memory management and component loading level, and goes all the way up to multiple ways of rendering user and program interfaces. In between, there are layers that provide just about any system-level capability that a developer would need.

At the base is the Common Language Runtime, often abbreviated to CLR. This is the heart of the .NET framework, the engine that drives key functionality. It includes, for example, a common system of data types. These common types, plus a standard interface convention, make cross-language inheritance possible. In addition to allocation and management of memory, the CLR also does reference counting for objects, and handles garbage collection.

The middle layer includes the next generation of standard system services such as ADO.NET and XML. These services are brought under the control of the framework, making them universally available and standardizing their usage across languages.

The top layer includes user and program interfaces. Windows Forms (often informally referred to as WinForms) are a new way to create standard Win32 desktop applications, based on the Windows Foundation Classes (WFC) produced for J++. Web Forms provide a powerful, forms-based UI for the web. Web Services, which are perhaps the most revolutionary, provide a mechanism for programs to communicate over the Internet using SOAP. Web Services provide an analog of COM and DCOM for object brokering and interfacing, but based on Internet technologies so that allowance is made for integration even with non-Microsoft platforms. Web Forms and Web Services, comprise the Internet interface portion of .NET, and are implemented through a section of the .NET Framework referred to as ASP.NET.

All of these are available to any language that is based on the .NET platform. For completeness, there is also a console interface that allows creation of character-based applications (not shown in the diagram).

The Common Language Runtime

Let's start with a definition. A runtime is an environment in which programs are executed. The Common Language Runtime is therefore the environment in which we run our .NET applications that have been compiled to a common language, namely Microsoft Intermediate Language (MSIL), often referred to simply as IL. Runtimes have been around even longer than DOS, but the Common Language Runtime (CLR) is as advanced over traditional runtimes as a light bulb is over a candle. Here's a quick diagrammatic summary of the major pieces of the CLR:

That small part in the middle, called Execution Support, contains most of the capabilities normally associated with a language runtime (such as the VBRUNxxx.DLL runtime used with Visual Basic). The rest is new, at least for Microsoft platforms.

Chapter 2 of this book will go into the Common Language Runtime in depth. However, since understanding the CLR is key to understanding the rest of .NET, here is a short introduction.

Key Design Goals

The design of the CLR is based on the following goals:

  • Simpler, faster development
  • Automatic handling of "plumbing" such as memory management and process communication
  • Good tool support
  • Scalability

Let's look at each of these in detail.

Simpler, Faster Development

A broad, consistent framework allows developers to write less, and reuse more. Less code is possible because the system provides a rich set of underlying functionality. Programs in .NET access this functionality in a standard, consistent way, requiring less "hardwiring" and customization logic to interface with these functions than is typically needed today.

Getting Rid of Plumbing

A lot of programming infrastructure is either handled automatically by the CLR or rendered completely unnecessary. That is, some of it is hidden, and some of it is just not there any more.

Memory management is an example of hidden infrastructure. Visual Basic developers stopped worrying too much about memory long ago. Today, C++ developers still have to, but not with the CLR, which has memory management functions built-in (though C++ developers have the option to do it themselves, and such unmanaged code is in fact the default for C++). If a C++ developer chooses to take full advantage of the CLR, it becomes unnecessary to use CoCreateInstance, for example, to instantiate a class, or malloc to set aside space for an array. A simple declaration statement will do it, and the CLR allocates the memory as necessary. Then it goes on to handle reference counting on instantiations and automatically do garbage collection when the reference count gets to zero.

Another example is proxies and stubs, which map interfaces on a remote object to the local system. The proxy handles communication with the remote object, and stands in its place locally, so that local processes can treat the remote object as if it were local, and the details of remote management are all handled behind the scenes. Contrast this with the work that is currently necessary to make DCOM work.

A lot of the missing plumbing is replaced by metadata - standardized information about components, interfaces, and processes that can be accessed in a consistent way. No more cycling through IUnknown to find out how to work with an interface - the CLR provides more flexible and much easier to use equivalents. A later section of this chapter covers metadata in more detail.

Tool Support

Though much of what the CLR does is similar to operating system functionality, it is designed first and foremost to support development languages. It furnishes a rich set of object models that are useful to tools like designers, wizards, debuggers, and profilers. And since the object models are at the runtime level, such tools can be designed to work across all languages that use the CLR. It is anticipated that third parties will produce a host of such tools.

It's also important to note that Microsoft is not restricting use of the CLR to Microsoft languages. Third party language vendors are encouraged to re-architect their languages to use the CLR, which offers a host of benefits. Besides taking advantage of all the CLR functionality (and thereby not having to write it or support it), using the CLR enables never before seen levels of cross-language integration. We'll discuss more of that later in the section on Multiple Language Support.

This capability of the CLR to work transparently with multiple languages has some huge benefits for developers. Debuggers offer the best example. The CLR makes it possible to write a source-level debugger that treats all languages equally, jumping from one language to another as necessary.

Simpler, Safer Deployment

It's hard for an experienced Windows component developer to see how anything can work without registration, GUIDs, and the like, but the CLR does. Applications produced in the .NET framework can be designed to install with a simple XCOPY. That's right - just copy the files onto the disk and run the application. We haven't seen this since the days of DOS (and some of us really miss it). This can work because compilers in the .NET framework embed identifiers (in the form of metadata, discussed below) into compiled modules, and the CLR manages those identifiers automatically. The identifiers provide all the information needed to load and run modules, and to locate related modules.

As a great by-product, the CLR can manage multiple versions of the same component (even a shared component), and have them run side-by-side. The identifiers tell the CLR which version is needed for a particular compiled module because such information is captured at compile time. The runtime policy can be set in a module to use the exact version of a component that was available at compile time, to use the latest compatible version, or to specify an exact version. The bottom line is that .NET is intended to eradicate "DLL Hell" once and for all.

This has implications that might not be apparent at first; for example, if a program needs to run directly from a CD (without first running an installation program). This was not feasible in Visual Basic after version 3, but the capability will reappear with Visual Basic.NET.

Another significant deployment benefit in .NET is that applications only need to install their own core logic. An application produced in .NET will not need to install a runtime, for example, or modules for ADO or XML. Such base functionality will be part of the .NET Framework, which will be installed separately and only once for each system. Those four-diskette installs for a VB "Hello, world" program will be a thing of the past!

Making all of this work automatically requires a sophisticated security infrastructure. The .NET Framework captures the origin of a piece of code, and the publisher of a module can be identified with a public encryption key. This allows a system to be set up so that it doesn't run untrusted software, which provides mechanisms to block viruses like the infamous ILOVEYOU. A method of a component, no matter how deep it is in the object model, can demand proof of authorization to run all the way back along the call chain that got to it.

Scalability

Since most of the system-level execution functions are concentrated in the CLR, they can be optimized and architected to allow a wide range of scalability for applications produced in the .NET Framework. As with most of the other advantages of the CLR, this one comes to all applications with little or no effort.

Memory and process management is one area where scalability can be built in. The memory management in the CLR is self-configuring and tunes itself automatically. Garbage Collection (reclaiming memory that is no longer being actively used) is highly optimized, and the CLR supports many of the component management capabilities of MTS/COM+ (such as object pooling). The result is that components can run faster, and thus support more users.

This has some interesting side effects. For example, the performance and scalability differences among languages become smaller. All languages compile to a standard byte code (IL - the Microsoft Intermediate Language), and there is discussion below on how the CLR executes IL. With all languages compiling down to similar byte code, it becomes unnecessary in most cases to look to other languages when performance is an issue. The difference in performance among .NET languages is minor - Visual Basic, for example, gives about the same performance as any of the other .NET languages.

There are early-stage plans for the CLR to be available on a wide range of devices. Eventually the vision is for .NET to be running at all levels, from smart palm-tops all the way up to web farms. That means the same development tools should work across the entire range - news that will be appreciated by those who have tried to use Windows CE development kits. Of course, this is an ambitious plan and may be subject to changes and retractions.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“There's no test like production” - Anon