Chapter 2. The Microsoft .NET Framework
Provided by: Thearon Willis, Bryan Newsome
This topic contains the following sections.
- Microsoft’s Reliance on Windows
- Writing Software for Windows
- Common Language Runtime
- The Common Type System and Common Language Specification
The .NET Framework provides an unprecedented platform for building Windows, web, and mobile applications with one or more languages. It is a definitive guide, encompassing and encapsulating where we have come from as a development community and, of course, where we are going.
.NET has been a success in many respects. Within the .NET Framework, new languages (C# and J#) have been born, and the well-established Visual Basic language has been reborn. The .NET Framework even supports legacy languages such as C++.
The .NET Framework provides the base for all development using Visual Studio 2008. It provides base classes, available to all Visual Studio 2008 languages for such functions as accessing databases, parsing XML, displaying and processing Windows and Web forms, and providing security for your applications. All languages in Visual Studio 2008 share and use the same base classes, making your choice of a programming language in Visual Studio 2008 a matter of personal preference and syntax style.
In this chapter, you will examine the following topics:
What the .NET Framework is
The .NET vision
Why Microsoft dared to spend $2 billion on a single development project
In terms of the great corporations of the world, Microsoft is still a new kid on the block. It is a fabulously rich and successful business. Nonetheless, the company has grown from nothing to a corporate superpower in a very short time.
What is perhaps more interesting is that although the origins of Microsoft can be traced to the mid-1970s, it is really the Windows family of operating systems that has brought the company great success. Based on Presentation Manager for OS/2, Windows has seen many incarnations from Windows/286 to Windows Vista, but the essential way that you use Windows and Windows applications has not changed in all that time. (Granted, there have been advances in the user interface and the hardware, but you still use the version of Excel included with Office 2007 in roughly the same way that you used the first version.)
The scary thing to Microsoft and its investors is that the pace of technological change means that they cannot be sure that Windows is going to be as relevant in 2011 as it is today. All it takes is one change in the way that people want to use computers, and the Windows platform’s current incarnation may become obsolete.
It is unfair to say that Microsoft has been extremely lucky over the past several years in the way that it has reacted to the opportunities offered by the Internet. Do not underestimate the number of smart people working for that company. When they discovered that companies like Netscape were making money with the Internet and identified the risk, they turned a large corporation on a dime and went after an unexplored market with teeth bared. Their gambles paid off, and with the invention of the .NET Framework, corporations and users are leveraging the power of the Internet in new ways.
Luckily for Microsoft, the applications that drove the adoption of the Internet worked well on a desktop operating system. Microsoft managed to adapt the Windows platform to provide the two killer Internet applications (e-mail and the Web browser) to the end user with a minimum of hassle, securing the Windows platform for another few years. It also delivered several powerful tools for developers, such as Active Server Pages Extended (ASPX), web services, and Internet Information Server (IIS), and improved existing tools such as Visual Basic and SQL Server, all of which made it easier for developers to build advanced Internet applications.
When the Internet started to become popular in the early 1990s, Microsoft was trying to push the original incarnation of Microsoft Network (MSN). Rather than the successful portal that it is today, MSN was originally a proprietary dial-up service much like CompuServe. In the beginning, MSN did not provide access to the rich world of the Internet as we know today; it was a closed system. Let us call the original MSN “MSN 1.0.”
MSN 1.0 provided an opportunity for innovative companies to steal a march on Microsoft, which was already seen as an unshakable behemoth thanks to the combination of Windows and Office. As it turned out, it was a missed opportunity.
Imagine an alternative 1995 in which Microsoft stuck to its guns with MSN 1.0, rather than plotting the course that brought it where it is today. Imagine that a large computer manufacturer, such as Dell, identified this burgeoning community of forward-thinking business leaders and geeks called the Internet. Also suppose Dell predicted that Microsoft’s strategy was to usurp this community with MSN 1.0—in other words, rather than cooperating with this community, Microsoft would decide to crush it at all costs.
Now Dell needs to find a way to build this community. It predicts that home users and small businesses will love the Internet and so puts together a very low-cost PC. They need software to run on it and, luckily, they predict that the Web and e-mail will be the killer applications of this new community. They find Linus Torvalds, who has been working on this thing called Linux since 1991, and they find Sun, which is keen to start pushing Java as a programming language to anyone who will listen. Another business partner builds a competent, usable suite of productivity applications for the platform using Java. Another business partner builds easy-to-use connectivity solutions that allow the computers to connect to the Internet and other computers in the LAN, easily and cheaply.
Dell, Sun, and their selected business partners start pushing this new computer to anyone and everyone. The concept is a success and, for the first time since 1981, the dominance of the IBM-compatible PC is reduced, and sales of Microsoft products plummet. All because Microsoft did not move on a critical opportunity.
We all know that this did not happen, but there is nothing outlandish or crazy about this scenario. It could have happened, and that is what scared Microsoft. It came very close to losing everything, and .NET is its insurance against this happening again.
The .NET Vision
To understand .NET, you have to ignore the marketing hype from Microsoft and really think about what it is doing. With the first version of the .NET Framework and indeed even now, Microsoft appears to be pushing .NET as a platform for building web services and large-scale enterprise systems. Although we cover web services in Chapter 21, it is a tiny, tiny part of what .NET is all about. In simple terms, .NET splits an operating system’s platform (be it Windows, Linux, Mac OS, or any other OS) into two layers: a programming layer and an execution layer.
All computer platforms are trying to achieve roughly the same effect: to provide applications to the user. If you wanted to write a book, you would have the choice of using the word processor in StarOffice under Linux, or Word under Windows. However, you would be using the computer in the same way; in other words, the application remains the same irrespective of the platform.
It is a common understanding that software support is a large part of any platform’s success. Typically, the more high-quality the available software is for a given platform, the larger the consumer adoption of that platform will be. The PC is the dominant platform because, back in the early 1980s, it was the predominant target for software writers. That trend has continued to this day, and people are writing applications that run on Windows, which targets the 32-bit and 64-bit Intel processors. The Intel processor harks back to the introduction of the Intel 8086 processor in 1979 and today includes the Intel Core 2 Duo, Intel Core 2 Quad, and Intel Xeon processors, and competitors like AMD’s Athlon and Turion.
So without .NET, developers are still reliant on Windows, and Windows is still reliant on Intel. Although the relationship between Microsoft and Intel is thought to be fairly symbiotic, it is reasonable to assume that the strategists at Microsoft, who are feeling (rightly) paranoid about the future, might want to lessen the dependence on a single family of chips too.
The Windows/Intel combination (sometimes known as Wintel) is also known as the execution layer. This layer takes the code and runs it—simple as that.
Although .NET originally targeted and still targets only the Windows platform, you are seeing development communities using open-source projects to convert .NET to run on other platforms such as Linux and Unix. What this means is that a program written by a .NET developer on Windows could run unchanged on Linux. In fact, the Mono project (www.mono-project.com) has already released several versions of its product. This project has developed an open source version of a C# and VB.NET compiler, a runtime for the Common Language Infrastructure (CLI, also known as the Common Intermediate Language or CIL), a subset of the .NET classes, and other .NET goodies independent of Microsoft’s involvement.
.NET is a programming layer. It is totally owned and controlled by Microsoft. By turning all developers into .NET programmers rather than Windows programmers, software is written as .NET software, not Windows software.
To see the significance of this, imagine that a new platform is launched and starts eating up market share like crazy. Imagine that, like the Internet, this new platform offers a revolutionary way of working and living that offers real advantages. With the .NET vision in place, all Microsoft has to do to gain a foothold on this platform is develop a version of .NET that works on it. All of the .NET software now runs on the new platform, lessening the chance that the new platform will usurp Microsoft’s market share.
This Sounds like Java
Some of this does sound a lot like Java. In fact, Java’s mantra of “write once, run anywhere” fits nicely into the .NET doctrine. However, .NET is not a Java clone. Microsoft has a different approach.
To write in Java, developers were expected to learn a new language. This language was based on C++, and although C++ is a popular language, it is not the most popular language. In fact, the most popular language in terms of number of developers is Visual Basic, and, obviously, Microsoft owns it. Some estimates put the number of Visual Basic developers at approximately three million worldwide, but bear in mind that this number includes both Visual Basic professionals and people who tinker with macros in the various Office products.
Whereas Java is “one language, many platforms,” .NET is “many languages, one platform, for now.” Microsoft wants to remove the barrier to entry for .NET by making it accessible to anyone who has used pretty much any language. The two primary languages for .NET are Visual Basic 2008 and C#. Visual Studio 2008 comes supplied with both of these. Although C# is not C++, the developers of C++ applications should be able to migrate to C# with about the same amount of relearning that a Visual Basic 6 developer will have to do in order to move to Visual Basic 2008. Of course the .NET Framework supports developers using C++ and allows them to write C++ applications using the .NET Framework.
Microsoft’s .NET strategy is more like a military campaign. First, it will use its understanding of the Windows platform to build .NET into something that will stand against a native C++ application. After it wins over the voters on Windows, it may invade another platform, most likely Linux. This second stage will prove the concept that .NET applications can be ported from one platform to the next. After invading and conquering Linux, it may move to another platform. Microsoft has been attempting to shake Solaris from the top spot in the server market for a long time, so it’s likely that it’ll go there next.
Microsoft has bet its future on .NET and rightly so with its ever-increasing adoption by developers and businesses alike. With developers writing software for the programming layer rather than an execution layer, it really does not matter whether Windows or Linux or some other software is the dominant platform in 2011. The remainder of this chapter drills into the mechanics of .NET and takes a detailed look at how the whole thing works.
To understand how .NET works, you need to look at how developers used to write software for Windows. The general principle was the same as with .NET, only they had to do things in different ways to work with different technologies—the Component Object Model (COM), ActiveX Data Objects (ADO), and so forth.
Any software that you write has to interact with various parts of the operating system to do its job. If the software needs a block of memory to store data in, it interacts with the memory manager. To read a file from disk, you use the disk subsystem. To request a file from the network, you use the network subsystem. To draw a window on the screen, you use the graphics subsystem, and so on.
This subsystems approach breaks down as far as .NET is concerned, because there is no commonality between the ways you use the subsystems on different platforms, despite the fact that platforms tend to have things in common. For example, even if you are writing an application for Linux, you may still need to use the network, disk, and screen subsystems. However, because different organizations developed these platforms, the way you open a file using the Linux platform may be different from the way you do it on Windows. If you want to move code that depends on one platform to another, you will probably have to rewrite portions of the code. You will also have to test the code to ensure it still works as intended.
Windows software communicates with the operating system and various subsystems using something called the Windows 32-bit Application Programming Interface (Win32 API). Although object-orientation in programming was around at the time, this API was designed to be an evolution of the original Windows API, which predates the massive adoption of object-oriented techniques that are discussed in Chapter 11.
It is not easy to port the Win32 API to other platforms, which is why there is no version of the Win32 API for Linux even though Linux has been around for over a decade. There is a cut-down version of the Win32 API for the Mac, but this has never received much of an industry following.
The Win32 API provides all basic functionality, but now and again, Microsoft extends the capabilities of Windows with a new API. A classic example is the Windows Internet API, also known as the WinInet API. This API allows an application to download resources from a web server, upload files to an FTP server, discover proxy settings, and so on. Again, it is not object oriented, but it does work. Another example of this is the Win32 API that is part of the Windows Vista operating system. Since so many of the core components of the operating system have changed, a new version of the Win32 API had to be developed for this operating system.
A large factor in the success of early versions of Visual Basic is that it took the tricky-to-understand Win32 API calls and packaged them in a way that could be easily understood. Using the native Win32 API, it takes about a hundred lines of code to draw a window on the screen. The same effect can be achieved in Visual Basic with a few gestures of the mouse. Visual Basic represents an abstraction layer on top of the Win32 API that makes it easier for developers to use.
A long-time frustration for C++ developers was that a lot of the things that were very easy to do in Visual Basic remained not so much hard as laborious in C++. Developers like C++ because it gives them an amazing amount of control over how a program works, but their programs take longer to write. Microsoft introduced the Microsoft Foundation Classes (MFC) because of this overhead, which, along with the IDE of Visual Studio, brought the ease of Visual C++ development closer to that of Visual Basic.
The .NET Framework Classes
Unlike the Win32 API, .NET is totally object-oriented. Anything you want to do in .NET, you are going to be doing with an object. If you want to open a file, you create an object that knows how to do this. If you want to draw a window on the screen, you create an object that knows how to do this. When you get to Chapter 11, you will discover that this is called encapsulation; the functionality is encapsulated in an object, and you don’t really care how it’s done behind the scenes.
Although there is still the concept of subsystems in .NET, these subsystems are never accessed directly—instead they are abstracted away by the Framework classes. Either way, your .NET application never has to talk directly to the subsystem (although you can do so if you really need or want to). Rather, you talk to objects, which then talk to the subsystem. In Figure 2–1, the box marked System.IO.File is a class defined in the .NET Framework.
If you are talking to objects that talk to subsystems, do you really care what the subsystem looks like? Thankfully the answer is “no,” and this is how Microsoft removes your reliance on Windows. If you know the name of a file, you use the same objects to open it whether you are running on a Windows Vista machine, a Pocket PC, or even, the Mono Project version of the .NET Framework, Linux. Likewise, if you need to display a window on the screen, you do not care whether it is on a Windows operating system or on a Mac.
The .NET Framework is actually a set of classes called base classes. The base classes in the .NET Framework are rather extensive and provide the functionality for just about anything that you need to do in a Windows or Web environment, from working with files to working with data to working with forms and controls.
The class library itself is vast, containing several thousand objects available to developers, although in your day-to-day development you will only need to understand a handful of these to create powerful applications.
Another really nice thing about the base classes in the .NET Framework is that they are the same irrespective of the language used. So, if you are writing a Visual Basic 2008 application, you use the same object as you would from within a C# application. That object will have the same methods, properties, and events, meaning that there is very little difference in capabilities between the languages, since they all rely on the framework.
The base class library is only half the equation. After you have written the code that interacts with the classes, you still need to run it. This poses a tricky problem; to remove the reliance on the platform is to remove the reliance on the processor.
Whenever you write software for Windows, you are guaranteed that this code will run on an Intel chip. With .NET, Microsoft does not want to make this guarantee. It might be that the dominant chip in 2011 is a Transmeta chip, or something you have never yet seen. What needs to be done is to abstract .NET from the processor, in a similar fashion to the way .NET is abstracted from the underlying subsystem implementations.
Programming languages are somewhere in between the languages that people speak every day and the language that the computer itself understands. The language that a computer uses is the machine code (sometimes called machine instructions or machine language) and consists entirely of zeros and ones, each corresponding to electrical current flowing or not flowing through this or that part of the chip. When you are using a PC with an Intel or competing processor, this language is more specifically known as x86 machine instructions.
If you wrote an application with Visual Basic 6, you had to compile it into a set of x86 machine instructions before you could deploy it. This machine code would then be installed and executed on any machine that supported x86 instructions and was also running Windows.
If you write an application with Visual Basic 2008, you still have to compile the code. However, you do not compile the Visual Basic 2008 code directly into x86 machine instructions, because that would mean that the resulting program would run only on processors that support this language—in other words, the program would run only on Intel chips and their compatible competitors. Instead, compilation creates something called Microsoft Intermediate Language (MSIL). This language is not dependent on any processor. It is a layer above the traditional machine code.
MSIL code will not just run on any processor, because processors do not understand MSIL. To run the code, it has to be further compiled, as shown in Figure 2–2, from MSIL code into the native code that the processor understands.
However, this approach also provides the industry with a subtle problem. In a world where .NET is extremely popular (some might say dominant), who is responsible for developing an MSIL-to-native compiler when a new processor is released? Is the new processor at the mercy of Microsoft’s willingness to port .NET to the chip? Time will tell.
Next, take a look at the thing that makes .NET work: the Common Language Runtime.
The Common Language Runtime (CLR) is the heart of .NET. CLR takes your .NET application, compiles it into native processor code, and runs it. It provides an extensive range of functionalities for helping applications run properly:
Code loading and execution
Do not worry if you do not understand what all these are—the following sections discuss all of them except for memory management. Memory management is quite a complex subject and is discussed in Chapter 12.
Code Loading and Execution
The code loading and execution part of the CLR deals with reading the MSIL code from the disk and running it. It compiles the code from MSIL into the native language (machine code) that the processor understands.
Java also has a concept similar to MSIL, known as byte code, which the Java runtime loads and executes.
One important premise of modern operating systems like Windows and Linux is that applications are isolated from one another. This is critically important from both security and stability standpoints.
Imagine that you have a badly written program and it crashes the PC. Should this happen? No, you want only the badly behaved program to crash, as you do not want other applications or the operating system itself to be affected by a program running on it. For example, if your e-mail program crashes, you do not want to lose any unsaved changes in your word processor. With proper application isolation, one application crashing should not cause others to crash.
In some instances, even under Windows XP, a badly behaved program can do something so horrendous that the entire machine crashes. This is commonly known as a Blue Screen of Death (BSOD), so called because your attractive Windows desktop is replaced with a stark blue screen with a smattering of white text explaining the problem. This problem should be alleviated in .NET, but it is unlikely to be completely solved.
The other aspect to application isolation is one of security. Imagine that you are writing a personal and sensitive e-mail. You do not want other applications running on your computer to be able to grab, or even stumble across, the contents of the e-mail and pass it on to someone else. Applications running in an isolated model cannot just take what they want. Instead, they have to ask whether they can have something, and they are given it only if the operating system permits it.
This level of application isolation is already available in Windows. .NET extends and enhances this functionality by further improving it.
.NET has powerful support for the concept of code security. The Framework was designed to give system administrators, users, and software developers a fine level of control over what a program can and cannot do.
Imagine that you have a program that scans your computer’s hard disk looking for Word documents. You might think this is a useful program if it is the one that you run to find documents that are missing. Now imagine that this program is delivered through e-mail and it automatically runs and e-mails copies of any “interesting” documents to someone else. You are less likely to find that useful.
This is the situation you find yourself in today with old-school Windows development. To all intents and purposes, Windows applications have unrestricted access over your computer and can do pretty much anything they want. That is why the Melissa and I Love You–type viruses are possible—Windows does not understand the difference between a benign script file you write that, say, looks through your address book and sends e-mails to everyone, and those written by others and delivered as viruses.
Windows Vista solves this problem by locking down the security aspects of Windows applications. If an application is not properly signed, Vista will prompt you for permission to let the program run. Likewise, Vista will prompt you for any program needing administrative permission to do operating system tasks. You then have the option of letting these programs run or canceling them, thus protecting your computer from these rogue viruses.
With .NET this situation changes because of the security features built into the CLR. Under the CLR, code requires evidence to run. This evidence can consist of policies set by you and your system administrator, as well as the origin of the code (for example, whether it came off your local machine, off a machine on your office network, or over the Internet).
Security is a very involved topic and is addressed only briefly in Appendix C of this book. However, you can find many books that cover only the topic of .NET security and it is worthwhile to find the book that best meets your needs.
Interoperation in the .NET Framework is achieved on various levels not covered here. However, we must point out some of the types of interoperation that it provides. One kind of interoperation is at the core of the framework, where data types are shared by all managed languages. This is known as the Common Type System (CTS). This is a great improvement for language interoperability (see the section “The Common Type System and Common Language Specification” later in this chapter).
The other type of interoperation is that of communicating with existing Component Object Model (COM) interfaces. Because a large application-software base is written in COM, it was inevitable that .NET should be able to communicate with existing COM libraries. This is also known as COM interop.
Exception handling is the concept of dealing with exceptional happenings when you are running the code. Imagine that you have written a program that opens a file on disk. What if that file is not there? Well, the fact that the file is not there is exceptional, and you need to handle it in some way. It could be that you crash, or you could display a window asking the user to supply a new file name. Either way, you have a fine level of control over what happens when an error does occur.
.NET provides a powerful exception handler that can catch exceptions when they occur and give your programs the opportunity to react and deal with the problem in some way. Chapter 10 talks about exception handling in more detail, but for now, think of exception handling as something provided by the CLR to all applications.
One of the most important aspects of .NET that Microsoft had to get right is inter-language operation. Remember, Microsoft’s motivation was to get any developer using any language to use .NET, and for this to happen, all languages had to be treated equally. Likewise, applications created in one language have to be understood by other languages. For example, if you create a class in Visual Basic 2008, a C# developer should be able to use and extend that class. Alternatively, you may need to define a string in C#, pass that string to an object built in Visual Basic 2008, and make that object understand and manipulate the string successfully.
The Common Type System (CTS) allows software written in different languages to work together. Before .NET, Visual Basic and C++ handled strings in completely differently ways, and you had to go through a conversion process each time you went from one to the other. With the CTS in place, all .NET languages use strings, integers, and so on in the same way, and therefore no conversion needs to take place.
In addition, the Common Language Specification (CLS) was introduced by Microsoft to make it easier for language developers to adapt their languages to make them compatible with .NET.
The Common Type System and Common Language Specification are the foundation for this interoperation, but detailed discussion is, unfortunately, beyond the scope of this book.
When talking to other .NET developers, you will likely hear the term managed code. This simply describes code that runs inside the CLR. In other words, you get all of the advantages of the CLR, such as the memory management and all of the language interoperability features previously mentioned.
Code written in Visual Basic 2008 and C# is automatically created as managed code. C++ code is not automatically created as managed code, because C++ does not fit well into the memory management scheme implemented by the CLR. You can, if you are interested, turn on an option to create managed code from within C++, in which case you use the term managed C++.
Hand-in-hand with managed code is managed data. As you can probably guess, this is data managed by the CLR, although in nearly all cases this data actually consists of objects. Objects managed by the CLR can easily be passed between languages.
This chapter introduced the Microsoft .NET Framework and explained why Microsoft chose to radically change the way programs were written for Windows. You also saw that part of Microsoft’s motivation for this was to move the dependence of developers from the execution platform (Windows, Linux, whatever) over to a new programming platform that it would always own.
After learning about why Microsoft developed .NET, you saw how writing for it is not much different from writing for Windows. You still have a layer that you program against; it is just that now, rather than being flat like the Win32 API, it is a rich set of classes that allows you to write true object-oriented programs no matter what .NET language you choose to develop in. This chapter also discussed how these classes could be ported to other platforms and how your applications could transfer across.
Finally, you looked at some of the more technical aspects of the .NET Framework, specifically the Common Language Runtime.
To summarize, you should now understand:
Microsoft’s new business venture
The goals of the .NET Framework
The abstractions that the .NET Framework provides
An introduction to the core of the .NET Framework
Beginning Microsoft® Visual Basic® 2008, Copyright © 2008 by Wiley Publishing, Inc., ISBN: 978-0-470-19134-7, Published by Wiley Publishing, Inc., All Rights Reserved. Wrox, the Wrox logo, Wrox Programmer to Programmer, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc and/or its affiliates.