Chapter 1: Microsoft .NET Framework Primer for the Visual Basic Developer
Summary: Develop more productive, secure, reliable, and deployable Visual Basic programs with innovations available in the .NET Framework. (33 printed pages)
The Applications You Can Build
A Truly Integrated Development Environment
What Is .NET?
The Common Language Runtime and Intermediate Language
Common Type System
Framework Class Library
Assemblies and Metadata
Data Access: ADO.NET
Similarities and Differences Between Visual Basic 6 and Visual Basic 2005
Important New Features in Visual Basic 2005
Similarities and Differences Between ASP, ASP.NET 1.0, and ASP.NET 2.0
Important New Features of ASP.NET 2.0
Enhancements in Visual Studio 2005 and the .NET Framework 2.0
The Microsoft .NET Framework and the corresponding versions of Microsoft Visual Studio that target the .NET Framework are major innovations for software developers. If you have been programming in Visual Basic 6 (or earlier), you will appreciate the advances in productivity, security, reliability, and "deployability" offered by these new development and execution environments.
Every program relies on its platform and other libraries to provide run-time services. Visual Basic 6 programmers know well the types of services provided by the Visual Basic Runtime. Java programmers use the Java Virtual Machine (JVM). Other programmers use the libraries for the technologies they develop with. The Microsoft .NET Framework class library provides a rich library for creating applications that run on the platform (or execution environment) known as the common language runtime (CLR). This chapter will introduce you to the basics of the .NET Framework, its class library, and the developer tools that make up Microsoft Visual Studio 2005. At the end of this chapter are some highlights of the new features in .NET Framework 2.0 and Visual Studio 2005 that are covered in more detail in the rest of this book.
The .NET Framework CLR is an execution environment that manages key platform services, including memory and security. Code that targets the .NET Framework is often referred to as managed code because it requires management services provided by the execution environment. All Visual Basic code you write for the .NET Framework is managed code. This includes Windows applications, Web applications, and all other types of applications.
You have probably heard a lot of hype about .NET and XML Web services. Much of that hype is well deserved because the .NET Framework and Visual Studio 2005 make building and consuming Web services so easy. But Microsoft .NET technologies are not just about Web services. Visual Studio 2005 and the .NET Framework are just as powerful for creating other types of applications, including Windows and Web applications. At times, the hype around Web services has overshadowed the wide range of applications you can create with Microsoft .NET technologies and the many benefits of targeting the .NET Framework, including increased security, increased developer productivity, decreased deployment and maintenance costs, and an extensive pre-built library for many generic tasks.
Smart Client Windows Applications
You can, of course, create GUI-driven Windows applications that are similar to the Windows applications you create with Visual Basic 6. These .NET applications are often called Windows Forms applications, thick clients, or smart clients. The Microsoft .NET Framework offers many features for Windows GUI applications that have been enhanced beyond Visual Basic 6 capabilities, such as docking, anchoring, opacity, new controls, and more Windows messages exposed as events.
The term smart client refers to Windows applications that combine the processing power and rich user interface (UI) of desktop applications with the deployment and connectivity features more generally associated with Web applications. Smart clients are conventional Windows applications with features such as the following: consuming Web services; supporting offline modes; deployable from a central server; providing automatic updates (from a central server); or supporting multiple types of devices. Interest in smart clients has been growing steadily as Microsoft technology simplifies deployment and companies struggle with the limits of Web based interfaces while looking for ways to use the processing power that sits at the edge of networks.
The .NET Framework has become an extremely popular technology for Web applications. The Web features in the .NET Framework, known collectively as ASP.NET, are embodied in a rich object model that provides power and scalability well beyond its predecessor ASP (now commonly known as classic ASP). Since its introduction, ASP.NET has been a highly effective set of technologies for creating and deploying everything from small to enterprise-scale Web applications.
XML Web services are part of ASP.NET. A conventional Web page responds to HTTP requests with HTML output. By contrast, Web services are based on SOAP, an XML-based protocol that defines the syntax and rules for exchanging messages between two systems. SOAP messages can be transported over HTTP just like Web page requests, which means you can expose services (for example, Web services) that are accessible through most firewalls that allow traffic on port 80.
Note The term dialect refers to the rules for a version of XML used to represent certain types of data. SOAP is an XML dialect for message exchange. There are countless other dialects of XML defined for many different uses of XML, including standards and proprietary systems.
A long-standing lament among Visual Basic programmers was the difficulty in creating applications that could run as Windows Services (formerly NT Services). Windows Services are background applications that perform tasks or provide services to other programs. Windows Services are normally started automatically and run regardless of whether any users are logged on. They are controlled by a Windows subsystem called the Service Control Manager. Prior to the .NET Framework, Visual Basic developers had to use third-party tools to create applications that could be run as services. Creating Windows Services applications with the .NET Framework is as easy as creating any other type of application. The service can be written in any .NET-compliant language, including Visual Basic.
An often overlooked but powerful type of application is the console application. Console applications have streams for input and output data rather than the point-and-click interaction model used for GUI applications. Console applications are often called command-line applications. Visual Basic 6 does not offer an easy way to create console applications, but with the .NET Framework you can create console applications in Visual Basic or any .NET-compliant language.
Maximizing code and binary reuse is a fundamental goal of professional developers. One way you work toward that goal is to design your software solutions so that code is generic and reusable. You then encapsulate that potentially reusable code in class libraries by generating DLL files. For Visual Basic 6 programmers, this process is somewhat analogous to creating a COM DLL project, except the DLL files created by Visual Studio 2005 are not COM components. They are assemblies that contain managed code. (Assemblies are covered later in this chapter.) The classes in these class libraries can be any sort of class, including controls and components (that you can then add to the toolbox in the Visual Studio 2005 IDE), classes that extend the Framework Class Library (for example, specialized forms), or your own classes that you implement completely (for example, classes for business rules).
Smart Device Applications
Windows, console, and Web applications (including Web services) target the .NET Framework. You can also write applications that target the .NET Compact Framework. The .NET Compact Framework is a subset of the full .NET Framework for smart devices. The .NET Compact Framework is optimized to run on devices with reduced resources like memory and screen size (for example, Smartphones and other handheld devices). Visual Studio 2005 includes a smart-device emulator to facilitate the development and debugging of smart-device applications.
Setup and Deployment Projects
You can create several types of setup and deployment projects with Visual Studio 2005. Setup and deployment projects are less important now than they used to be because many deployment issues have been simplified, including eliminating the need to register components used by a single application (that is, private assemblies). But there are still many situations in which you will want to have a robust and professional-looking installation program. Visual Basic 6 developers will find that the setup and deployment projects in Visual Studio 2005 are greatly improved over the Package and Deployment Wizard from Visual Basic 6. The power and flexibility of the development interface and the generation of MSI setup packages for Microsoft Installer gives Visual Basic developers access to features that were previously available only with third-party tools.
Visual Studio .NET introduced a unified development environment for all the types of applications you can build. Visual Studio 2005 is the latest offering in the evolution of that unified environment. It is a lot more than an integrated editor, compiler, and debugger. A common shell, shown in Figure 1-1, hosts the entire assortment of tools that makes up Visual Studio 2005, such as the Visual Basic code editor, the visual Windows Forms designer, the new visual Web designer, the Server Explorer, and much more. The shell is also extensible, allowing add-ins, macros, new project types, and new designers to be plugged into the development environment.
Figure 1-1. Visual Studio 2005 integrated development environment. (Click on the image for a larger picture)
The Visual Studio 2005 IDE (integrated development environment) is a robust working environment in which you will probably spend most of your development time. For example, in this one environment you can write a Web application storefront, a Windows service for processing financial transactions, a Web service for exposing data to multiple back-office systems, and a smart client for retrieving data via the Web service in the back office. You can also use the IDE to debug all these applications, run unit tests (with Visual Studio Team System), manage enterprise services (for example, MSMQ), manage SQL Servers, and more.
Understanding exactly what ".NET" means can be challenging. If you ask five experienced .NET developers "What is .NET?" you will probably get five different answers, just as you would get different answers if you asked "What is Microsoft Windows?" or "What is a computer program?" These differences arise because different types of users understand technologies from their own perspectives. From a developer's perspective, .NET is really three things: the .NET Framework, the .NET Framework SDK, and the development environment (first Visual Studio .NET, then Visual Studio .NET 2003, and now Visual Studio 2005).
The .NET Framework provides a core set of functionality for applications. It provides the services and other features necessary for code to run in a managed environment. The .NET Framework SDK is the set of base tools for creating managed applications and includes compilers along with a number of other useful tools. Visual Studio 2005 builds on the base tool set provided in the Framework SDK. Visual Studio is the premiere tool for developing applications that target the .NET Framework.
Note Some developers and IT professionals describe the .NET Framework as a platform, while others will insist that the .NET Framework is not a platform but a building block or ingredient in a broader platform, namely Microsoft Windows. Really the .NET Framework and the .NET Compact Framework are both platforms and building blocks of the broader platforms on which they sit, such as Windows Server 2003 or Windows CE. Those broader platforms run on hardware that is often referred to as a platform as well. To help reduce confusion with so many uses of the term platform, the .NET Framework is not referred to as a platform in this book.
Every program runs within a context. DOS programs ran within the context of the services provided by the 16-bit MS-DOS operating systems. Applications such as Microsoft Word run within the context of your current operating system and are subject to the constraints imposed and services provided by that operating system, such as the permissions granted to your user account. For example, on Windows XP and Windows Server 2003, applications have restricted access to the file system because the operating system runs applications within a security context and protects the file system with access control lists (ACLs).
The CLR is a core component of the .NET Framework that provides the context for managed code and executes that code. In some ways the CLR is a virtual machine, but the capabilities of the CLR extend beyond a simple virtual machine model. The CLR has a built-in understanding of its context and responds appropriately depending on the environment it finds itself in. For example, the CLR behaves differently in Windows 98 and Windows Me environments than it does in Windows XP or Windows Server 2003 because of fundamental differences between those two families of operating systems (MS-DOS-based versus Windows NT-based). The CLR also has the ability to behave differently in multiprocessor environments in order to leverage the benefit of multiple CPUs.
The CLR is an implementation of a standard known as the Common Language Infrastructure (CLI) that defines a machine-independent environment in which applications are executed. The CLR Virtual Execution System provides important services such as memory management (object lifetime management and garbage collection) and security. The CLR also provides a just-in-time (JIT) compiler for converting Intermediate Language into native code that can be executed by the physical CPU.
Intermediate Language (IL) is a new language designed to be efficiently converted into native machine code on different types of devices. IL is based on an abstract stack-based processor architecture. It is the lingua franca of the .NET Framework. The Visual Basic compiler, vbc.exe, generates IL. The C# compiler, csc.exe, generates IL. In fact, every .NET-compliant compiler generates IL. Intermediate Language is a lower level language than Visual Basic or C#. For programmers with a background in machine assembly languages, IL is reminiscent of assembly language but at a higher level of abstraction.
One of the tools included with the .NET Framework SDK is Ildasm.exe, the IL Disassembler. Ildasm is used to display the contents of a .NET program file in a human-readable form. Figure 1-2 shows part of the output from Ildasm for a simple Windows application.
Figure 1-2. Ildasm.exe showing a simple Windows application.
Ildasm can be used to view the IL within individual functions and subroutines (also known as methods in object-oriented languages). Figure 1-3 shows the IL listing for the Form1_Load method. The following code is the original Visual Basic source:
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim I As Integer Dim S As String For I = 1 To 20 S += I.ToString() + " " Next MsgBox(S) End Sub
Figure 1-3. IL listing for a simple subroutine. (Click on the image for a larger picture)
The .NET Framework SDK also includes an assembler, Ilasm. You can type Intermediate Language in your favorite text editor and then use Ilasm to assemble it. The assembled IL could then be executed on the CLR. Although it would certainly be an educational exercise for some, most professional programmers find it more expedient to program in Visual Basic, C#, or another high-level programming language and then generate IL using a .NET-compliant compiler.
Note Intermediate Language is sometimes called Microsoft Intermediate Language (MSIL) or Common Intermediate Language (CIL). MSIL is normally pronounced "missile."
If you consider, for a moment, that all .NET-compliant languages are compiled into IL, and that the CLR executes IL, you realize that all managed code is the same to the CLR regardless of the original high-level programming language used. All languages are first-class languages. Every .NET-compliant language has access to the full Framework Class Library. Every .NET programmer can reuse compiled IL created with any .NET-compliant language.
This is not to say that every .NET-compliant language is equal. Some languages are more appropriate than others for solving particular problems. Figure 1-4 shows a solution with a Windows application in Visual Basic that calls a method, GetNumberListString, from a class library in C#. Visual Basic and C# are both compiled into IL, so neither language is inherently faster than the other. However, different compiler settings can result in different IL for highlevel code that is semantically equivalent. A for loop in C# will run faster than the equivalent loop in Visual Basic if you use the default compiler settings because the Visual Basic compiler includes overflow checks by default, but the C# compiler does not (a typical safety-versus-speed tradeoff). If you are writing code with high-iteration loops, you could use C# with the compiler's overflow checking option turned on and then wrap the high-iteration loops in unchecked statement blocks to turn off overflow checking for specific blocks of code for a small performance gain. Visual Basic does not provide an option for turning overflow checking on and off at such a granular level, so this is one of the rare scenarios in which C# could be more appropriate for solving a specific problem. (Visual Basic has its own set of unique features, such as the My namespace and optional method parameters.)
Figure 1-4. Visual Basic code calling a method written in C#. (Click on the image for a larger picture)
The preceding example with a loop in C# is obviously a bit contrived. A loop body generally has to be unrealistically simplistic for the impact of integer overflow checking to be significant (unless, of course, the loop body contains mostly integer operations that would run faster without overflow checking). And unchecked integer operations are not exclusive to C#—you could factor the code out into a separate Visual Basic class library and disable overflow checking for that project only to obtain the same resultant IL. But even if this example is a bit contrived, there are many realistic scenarios in which you might use multiple .NET languages in the same solution. For example, you might have purchased third-party C# code that your Visual Basic project has to call into. Or your company might be like many development shops that have former ASP programmers building ASP.NET applications using Visual Basic .NET while their COM programming colleagues with a C++ background build class libraries in C# for the ASP.NET applications to consume. In that case, it is matter of letting programmers use the .NET languages that are most comfortable for them given their programming backgrounds.
Note Be careful when mixing multiple programming languages in your software solutions. Multiple languages can make it hard to refactor (restructure) code and can frustrate or confuse programmers who are not fluent in all the languages in use (especially junior-level coders). You should also beware of the difference between case-sensitive languages such as C# and case-insensitive languages such as Visual Basic. A public interface exposed by a C# component that differentiates between methods, properties, or fields by case only (for example, UserName vs. username) cannot be used as intended from a Visual Basic program.
If you have spent much time writing Visual Basic 6 code that calls the Win32 API, or functions exposed by a third-party DLL, you know that the built-in data types in Visual Basic 6 are different from the built-in data types in other languages (for example, C). If all .NET languages compile into IL that is callable from any .NET program, there has to be a common set of data types for representing integers, real numbers, dates, text, and so on in all those languages. The data types used by the .NET Framework are defined as part of the Common Type System, and are available equally to all .NET languages.
The Common Type System is fundamental in ensuring cross-language integration. A Visual Basic programmer can pass an Int32 value or a String to a C# library with complete confidence because Int32 and String are defined as part of the Common Type System. The Common Type System is also fundamental in ensuring type safety at runtime, which ensures that your code does not allow unauthorized memory access and is not vulnerable to certain types of security attacks.
Visual Basic has a number of primitive data types that map to predefined types in the Common Type System. For example, the Visual Basic primitive type Integer is an alias for System.Int32, a 32-bit integer. The Visual Basic primitive type String is an alias for System.String, a sequence of Unicode characters. C# and other languages have their own primitive data types that correspond to these same predefined types in the Common Type System.
Note In Visual Basic 6, an Integer is a 16-bit value and a Long is a 32-bit value. In Visual Basic code targeting the .NET Framework, Integer is 32 bits and Long is 64 bits. If you use the Visual Basic 6 Upgrade Wizard to convert your code, your integer data types will be adjusted for you by the wizard.
Objects and Values
There are two kinds of data types in the Common Type System: reference types and value types. These two data types are fundamentally different in how they are created, passed around in memory, and finally destroyed. Value types hold the values you would normally think of as primitives: integers, floating point numbers, characters, Boolean (true/false) values, and others.. Value types are generally simple to represent in memory, usually only requiring a few bytes. When value types are passed around in memory (for example, when they are passed as arguments to a method), the value itself is copied (by default).
Value types are simple and efficient. They do not require the same type of overhead required for creating objects (that is, reference types) and do not need special consideration for destruction. Values are stored directly on the stack and tied to a variable or constant (or literal). The lifetime of the value is the same as the lifetime of the variable used to access the value. A variable cannot be separated from its value, so a value type variable always has a value. Unlike reference types, value type variables cannot be null (Nothing).
The Common Type System defines the most useful value types (Integer, Double, Date, Char, and so forth) and allows you to define your own value types. You can also create enumerations, which are custom value types that contain symbolical aliases for a subset of the values of an integral type (normally Integer). Only the aliases specified in the enumeration definition are valid values for variables of the enumeration type. For example, the following code listing shows an enumeration for user types. A UserType variable can have only one of the three values specified (Admin, Moderator, or User).
Enum UserType As Integer Admin = 1 Moderator = 2 User = 3 End Enum
The .NET Framework Class Library makes extensive use of enumerations for everything from file I/O modes to colors.
Reference types are a very different kind of data type. The "value" of a reference type is the content of the memory location allocated to hold an instance of that reference type (that is, an object). The value of a reference type is always accessed via a reference to the memory location holding that value. Unlike value type variables, a reference type variable is not intrinsically tied to a fixed memory location that always has a value. A reference type variable can be a reference to any object in memory (of the appropriate data type). Or a reference type variable might not hold a reference to any object, in which case it is said to be a null reference or a reference to Nothing.
The CLR allocates space for objects (instances of reference types) in its runtime memory heap. Consider the following line of code.
conn = New SqlConnection(connectionString)
The variable conn is being assigned a reference to a new SqlConnection object. That object is created in the memory heap. The CLR allocates memory for the new object and calls a special method known as a constructor for the SqlConnection class. The CLR also takes on the responsibility of destroying that object and freeing its memory when the object is no longer in use and additional memory is needed. This is known as garbage collection and is one of the core services provided by the CLR.
When a reference type is passed as an argument to a method, the reference is passed by value. That means a copy is made of the reference, not the object value itself (in the memory heap). The original calling code and the method being called will both hold references to the same object in memory. If the method changes the content of that object, the change affects the calling code. Consider the following Visual Basic code.
Sub CreateDataSet() Dim ds As New DataSet AddTable(ds) ' ' The message box displays "1" because the AddTable method ' has changed the DataSet object ds. ' MsgBox(ds.Tables.Count.ToString()) End Sub Sub AddTable(ByVal targetDataSet As DataSet) targetDataSet.Tables.Add("TableOne") End Sub
The variable ds is a reference to a new DataSet object that is passed to the AddTable method. In the AddTable method, the variable targetDataSet is a reference to the same DataSet object. The AddTable method adds a new table to the DataSet. Then back in CreateDataSet, after calling AddTable, the DataSet object ds will have one table in its Tables collection. Both methods are working with the same DataSet object in memory even though there are two different variables in two different methods.
Classes, Methods, Properties, Fields, and Events
In object-oriented programming, objects are instances of classes. As a programmer, you define a class with data fields, properties, methods, and events. Then you create objects based on that class that have state (fields, properties) and behavior (methods, events). Consider the Form class as an example. The Form class defines the data and properties (for example, Width) for a window to be displayed in a Windows application. The Form class also defines behavior such as the Show method that displays a form. The Form class itself is not a form instance. The class defines what a Form object looks like and what it can do. An actual Form object would be a sequence of bytes at a specific memory location in the memory heap.
A class comprises four building blocks: fields, methods, properties, and events. A field is a value that a class holds. A field can hold a value directly (value type) or hold a reference to a value (reference type). A field in a class is somewhat analogous to a variable in a method. The value in a variable during a method call is part of the state of that method call, and the variable is tied to that "instance" of the method. Likewise, a field is part of the state of an object (that is, an instance of a class).
A method is a unit of functionality in a class. Subroutines (Sub) and functions (Function) in Visual Basic are methods. Methods are an important part of the behavior of an object. A method is something that an object can do. It is a block of programming logic that is executed within the context of an object, and it can access or manipulate the state of the object via its fields and properties.
A property is a hybrid between a field and a method. Like a field, a property is part of the state of an object. To other objects, a public property looks like a public field, and you use the same syntax for reading and writing property values. But internally, a property is actually two special methods: a Get procedure and a Set procedure. When you read the value of a property, the Get procedure is executed. When you set the value of a property the Set procedure is executed. Properties allow you to have logic associated with accessing values. More importantly, properties allow you to separate an object's public interface from the internal representation of its data.
An event is the other kind of behavior an object can exhibit. If a method is something an object can do, an event is something an object says. Normally events are used to notify listening objects of a change in state. Listening objects are "notified" via event handlers. A listening object registers a method as an event handler for a specific event of a specific object. That method (the event handler) is then called automatically when the event occurs. Events occur when they are explicitly raised by an object. For example, a Button object raises a Click event when it receives a message from Windows indicating that the default mouse button was pressed while the mouse pointer was over the button. If you have programmed in Visual Basic 6, you are already familiar with event-driven programming. You'll find some differences in how event handlers work in managed code, but in many cases the code you write is very similar to the code you would write in Visual Basic 6.
When you write managed code in Visual Basic .NET, you are always creating a class, which is the definition of a data type. The state and behavior of an object of that type is determined by your code. The following example is a class called UserAddress. This class contains four fields to hold the elements of a mailing address. In this example, the fields are all marked as Private, which means they are not accessible outside of the UserAddress class. Instead, the data is publicly exposed using four properties. The properties in UserAddress are simple wrappers around the private fields, but what is significant here is that the external (public) interface for the address is separate from the actual fields that hold the data. You could freely change the way the data is internally represented while continuing to expose the same external interface. This example also includes an event called AddressChanged. Each Set procedure in each property raises this event if the new value is different from the old value. Listening objects can register handlers for the AddressChanged event and execute code when the UserAddress state changes (that is, when some part of the address is changed). And finally, there is a GetFormattedAddress method that creates a new String object containing all the address data.
Public Class UserAddress Private _address As String Private _city As String Private _provState As String Private _postalCode As String Public Event AddressChanged() Public Property Address() As String Get Return _address End Get Set(ByVal Value As String) If _address <> Value Then _address = Value RaiseEvent AddressChanged() End If End Set End Property Public Property City() As String Get Return _city End Get Set(ByVal Value As String) If _city <> Value Then _city = Value RaiseEvent AddressChanged() End If End Set End Property Public Property StateProvince() As String Get Return _provState End Get Set(ByVal Value As String) If _provState <> Value Then _provState = Value RaiseEvent AddressChanged() End If End Set End Property Public Property PostalCode() As String Get Return _postalCode End Get Set(ByVal Value As String) If _postalCode <> Value Then _postalCode = Value RaiseEvent AddressChanged() End If End Set End Property Public Function GetFormattedAddress() As String Return _address + vbCrLf + _ _city + ", " + _provState + vbCrLf + _ _postalCode End Function End Class
The UserAddress class is a simple example of the kind of data types you can create in Visual Basic .NET. Building applications for the .NET Framework is a process of turning requirements into classes that interact to achieve the desired functionality. Sometimes you have to code an entire class yourself, such as with the UserAddress class. Other times, the class is created for you automatically by a wizard or some other tool, such as when you add a new form to your application.
Anything you need to do in your application you will do with a class. Need something that represents a customer? Create a class. Need functionality to move data from a legacy system to a Microsoft SQL Server database? Create a class. If you design your classes with reuse in mind, you will end up with a set of classes you can copy into new applications. The .NET Framework itself includes a large library of classes designed to be reused in many types of applications. This collection of classes is known as the Framework Class Library and has been one of the most popular aspects of the .NET Framework since its introduction.
Note In some object-oriented programming languages and abstract object models, the terms field, property, and attribute are used interchangeably. In the .NET Framework, properties and attributes are specific constructs that are distinct from fields.
A high-level programming language such as Visual Basic .NET that targets an execution environment such as the CLR is a powerful concept, but it must be accompanied by an equally powerful set of libraries to be truly useful in the real world. The Framework Class Library (FCL), sometimes called the Base Class Library (BCL), is a set of DLLs that form an integral part of the .NET Framework. Each DLL contains a related set of classes for providing some specific functionality. For example, System.Drawing.dll provides classes for generating graphics; System.DirectoryServices.dll provides classes for interacting with Active Directory; and System.Xml.dll provides classes for working with XML documents. The Framework Class Library contains everything from basic file I/O to the classes that make up ASP.NET and ADO.NET.
Most developers seem to find that the biggest task in becoming a proficient .NET developer is learning the Framework Class Library. Part of that task is learning new ways to do familiar things. The larger part of the task is learning the many new capabilities in the Framework Class Library that previously required a lot of custom code or third-party components. To ping a server, use the Ping and PingReply classes. To access a Web site programmatically, use the WebClient or HttpWebRequest classes. To validate the format of an e-mail address, use the Regex class. To transform an XML document, use the XslTranform class. To send an e-mail message programmatically, use the SmtpMail class.
The Framework Class Library is comprehensive enough that .NET developers will often confess that they spend an increased percentage of their time researching and finding the right classes from the Framework Class Library to accomplish general-purpose tasks (for example, converting a PNG image to a JPG image) and a decreased percentage of their time writing custom code to perform such tasks. Using the Framework Class Library for these tasks means having fewer lines of custom code to test, debug, and maintain as well as having prewritten documentation and support from other developers worldwide who are using the exact same classes to perform the same generic tasks.
This book focuses on the latest Framework Class Library features, which were introduced in version 2.0 of the .NET Framework. Many great sources are available for more in-depth information on the more established parts of the Framework Class Library, including the MSDN documentation that installs with Visual Studio 2005, information at the MSDN Web site, information that can be found by searching http://www.google.com/, and 101 Microsoft Visual Basic .NET Applications (available from Microsoft Press).
The Framework Class Library is organized as a hierarchy of namespaces. Namespaces provide a way to organize classes to help avoid ambiguity, reduce naming collisions, and group related classes together. Without an organizational structure, naming collisions would be frequent and frustrating. If you were working on a page layout program, you might want to create a class to represent a block of text on a page, but if you tried to create a TextBox class you would collide with the TextBox class defined for Windows forms. If you were working on a tool for managing legal forms, you might want to create a class to represent a form, but if you tried to create a Form class you would collide with the existing Form class in the Framework Class Library. Url? Already used. Semaphore? Already used. Ping? Timer? Thread? All are used already in the Framework Class Library. The list would go on and on—the Framework Class Library is extensive. Fortunately, the Framework Class Library uses namespaces to prevent the frustration of naming collisions. In fact, the Framework Class Library itself repeats some class names in different namespaces. Most notable are the user interface controls—such as TextBox, ListBox, and Button—that appear in both the System.Windows.Forms and System.Web.UI.WebControls namespaces (although these two namespaces are not usually used together in the same application).
As mentioned previously, the Framework Class Library is extensive and mastering it is not a trivial task. Namespaces make using the Framework Class Library much easier because classes with related functionality are usually found under the same namespace. If you need to work with data, you look in the System.Data namespace. If you need to work with XML, you look in the System.Xml namespace. If you need to read or write a file, you look in the System.IO namespace. Familiarizing yourself with the namespaces immediately under the System namespace (including some of the most prominent classes) will make you a much more efficient .NET programmer because you will be able to quickly identify in which namespace to search when looking for classes that provide some specific functionality you need.
When you create an application with Visual Studio 2005, your classes are placed in a namespace with the same name as your application. You can change that default root namespace via the Visual Studio 2005 project properties window as shown in Figure 1-5. Namespaces can be nested, so you can create additional namespaces in your code that will be placed under your project's root namespace in the namespace hierarchy. As the number of classes in your application or class library grows, you will find that creating namespaces for related sets of classes is useful for keeping your classes organized. If the root namespace for your application is ChooseYourOwnNamespace, the following code would define a class named Class1 in the ChooseYourOwnNamespace.Namespace1 namespace.
Namespace Namespace1 Public Class Class1 End Class End Namespace
Figure 1-5. Project properties window showing the root namespace setting for the project. (Click on the image for a larger picture)
Unless other information is provided for the compiler to resolve a class name, classes must be referred to using their fully qualified name. A fully qualified name is the class name preceded by its namespace. If the namespace is nested in another namespace, the full list of namespaces must be included in the fully qualified name. The fully qualified name for the class in the previous example is ChooseYourOwnNamespace.Namespace1.Class1. Of course, there are common namespaces you will use frequently and typing those fully qualified names over and over again would only serve to clutter your source code. As an alternative to typing fully qualified names, you can import namespaces into your entire project or into individual code files. Figure 1-6 shows namespaces imported into an entire project via the project properties window. Figure 1-7 shows several namespaces imported into a code file by using the project properties, or by using the Imports statement in your code.
Figure 1-6. Namespaces imported for a project. (Click on the image for a larger picture)
Figure 1-7. Namespaces imported for an individual code file. (Click on the image for a larger picture)
Applications are collections of functionality. Classes are the building blocks that contribute to the overall functionality of your applications. That functionality has to be bundled in such a way that it can be saved to storage media (for example, to hard disk or DVD), deployed to other computers, loaded by an execution environment (such as the CLR or the operating system for managed and unmanaged code, respectively), and in some cases reused by multiple applications. These "bundles" of functionality are called assemblies if they target the .NET Framework. In Windows-based environments there are two types of files that encapsulate functionality: executables (EXE files) and libraries (DLL files). An assembly is normally a single EXE or DLL file, although it is possible to create multifile assemblies. With Visual Studio 2005 (as well as Visual Studio .NET and Visual Studio .NET 2003), you can create both EXE and DLL assemblies.
Assemblies are the units of versioning and deployment for managed code. If an application is made up of one executable (EXE file) and one library (DLL file), you will have two assemblies, each with its own version number. You can deploy both files at the same time and then later deploy an updated DLL without deploying an updated executable.
Assemblies are made up of three things: Intermediate Language, metadata, and resources. As mentioned earlier, .NET compilers do not generate binary machine code, they generate Intermediate Language. The IL in an assembly is turned into binary machine code by the JIT compiler on a just-in-time basis—in other words, when the code is needed at runtime. The JIT compiled code is saved in memory so that it can be reused for subsequent executions of that code for the current process. JIT compilation is significantly different from interpreting code.
IL is relatively easy to convert to native machine code, and it can be optimized for the hardware and resources available at runtime. The small upfront compilation cost yields optimized binary code for the current environment.
The metadata stored in the assembly file is called the manifest. The manifest includes the assembly version, references to other assemblies, supported cultures, type information, and other self-describing information about the assembly.
The resources in an assembly are content files embedded in the assembly itself that can be accessed at runtime. One of the most common uses of embedded resources is image files. The following code sample shows how to read an embedded JPG image from the current assembly and show it in a PictureBox control. In this example, the embedded resource is Image1.jpg. The root namespace of the assembly is MyApp.
Private Sub LoadResourceImage() PictureBox1.Image = My.Resources.DiskImage End Sub
Although all managed code gets packaged into assemblies, you get different types of applications depending on the type of the assembly (EXE or DLL) and how that assembly is loaded. Windows applications are EXE files that are loaded by the Windows shell. Web applications are DLL files that contain specific types of classes that are loaded by IIS (Internet Information Services). Later in this chapter, Windows and Web applications are discussed in more detail, including differences between versions of Visual Basic, COM, and ASP, and important new features introduced in the .NET Framework 2.0.
Data access is an essential aspect of many applications. When you first learned to program, you probably read or heard someone say that a program is useless (or least not very interesting) without input and output. One source of input for an application is a data source such as a SQL Server database, a Microsoft Access data file, or an XML document. Visual Basic programmers have seen several data access technologies over the years, including DAO, RDO, and ADO. If you have programmed in Visual Basic 6, you have probably used ADO to read and write data from an OLEDB data source such as a SQL Server database. ADO was designed to work with relational data in a connected environment. Although support was tacked on to ADO for disconnected recordsets, it was limited. The ADO.NET data access API was introduced as an integral part of the Framework Class Library to provide better support for disconnected scenarios as well as first-class support for XML.
Disconnected data is a central concept in ADO.NET. Instead of there being a Recordset, a number of classes in the System.Data namespace provide more options for working with data than a Recordset provides. The central class in ADO.NET is DataSet. A DataSet object contains a collection of DataTable objects (and can contain DataRelation objects to define relationships between DataTable objects). A DataTable contains a collection of DataColumn objects that define the structure of the DataTable. A DataTable also contains a collection of DataRow objects that hold the data for the DataTable. A DataSet and its contained objects are generic and completely disconnected from an underlying data source.
There are several ways to populate a DataSet, including the option of creating a DataTable and its Columns collection programmatically and then writing the code to add DataRow objects to the Rows collection. A more common approach in Visual Studio .NET 2005 is to use another object called a data adapter to create the DataTable objects based on the structure of the data returned from the data source. This is where ADO.NET starts to get specific about data sources. A data adapter is part of what is known as a managed provider, which is a set of classes for a specific type of data source. The SqlClient managed provider is for accessing SQL Server. The OleDb managed provider is for accessing any OLEDB data source. There are other managed providers available for other types of data sources (for example, ODBC and Oracle). A managed provider defines classes for a connection, a command, a parameter, database types, a data adapter, and several other useful classes. The following code shows how to populate a DataSet from a SQL Server database:
Dim conn As New SqlConnection conn.ConnectionString = _ "server=(local);database=Northwind;Trusted_Connection=True" Dim adapter As SqlDataAdapter adapter = New SqlDataAdapter("SELECT * FROM Products", conn) Dim dsProducts As New DataSet conn.Open() adapter.Fill(dsProducts) conn.Close()
To submit changes made in a DataSet back to the data source, you can use the Update method of a data adapter. To do updates, the data adapter must have command objects (such as SqlCommand, OleDbCommand, and so on) available for inserting, updating, and deleting data.
You can create the command objects yourself, you can use a command builder object to autogenerate the command objects at runtime, or you can use a tool such as the TableAdapter Configuration Wizard in Visual Studio .NET 2005 to auto-generate the code to create the command objects.
Note The Data Adapter Configuration Wizard is still available in Visual Studio 2005; however, you should use it to edit only data adapters already present in code brought forward from Visual Studio .NET 2003. There are new tools and features for data access, which are discussed in Chapter 4, "Building Data-centric Applications."
After a DataSet object has been populated, it can be passed around to different parts of your application—even to distributed components—because the DataSet class is designed to be disconnected and ignorant of any data source. The flexibility and disconnected nature of the Dataset makes it much easier to build distributed applications that pass data around and to support important smart client scenarios such as offline use.
Visual Studio 2005 and .NET Framework 2.0 introduce some new options for data access tasks such as populating a DataSet. Visual Studio 2005 builds on the Data Adapters provided by Visual Studio 2003, and provides strongly typed Table Adapters for populating a DataSet objects. These new features and the new tools that support them, such as the Data Source Configuration Wizard, are discussed in detail in Chapter 4.
Windows application development has been a hallmark of Visual Basic since its introduction. Although much has changed about how a Windows application developed with Visual Basic compiles and executes, most of your development skills from Visual Basic 6 will transfer to Windows development with Visual Studio 2005.
If you have built applications with Visual Basic 6 (or earlier), you are well acquainted with the visual design and event-driven features that have made Visual Basic so popular. Visual Studio 2005 carries on the tradition of an easy-to-use visual design experience coupled with an event driven model.
The Visual Studio 2005 designer for Windows applications maintains enough of the look and feel of the visual designer from Visual Basic 6 that moving forward is quite easy. Figure 1-8 shows an example of a form in design view in Visual Studio 2005. You can position controls visually, add new controls from the toolbox, edit properties in the Properties window, and double-click a control to write an event handler.
Figure 1-8. Visual Studio 2005 visual Windows Forms designer. (Click on the image for a larger picture)
Although the designer is very similar at first glance, many enhancements make Windows Forms development easier while giving you more power and flexibility. One of the most significant changes from Visual Basic 6 is that all controls and other UI components are actually classes in the Framework Class Library. When you drag a TextBox onto a form, Visual Studio 2005 auto-generates a field to hold a reference to a TextBox object and writes the code for instantiating a TextBox object when the form is initialized. The visual designer also writes the code for setting the properties of the control. If you change the BackColor property of the TextBox in the Properties window, Visual Studio 2005 generates a line of Visual Basic code that sets the BackColor. Figure 1-9 shows some of the auto-generated code for the login form shown in Figure 1-8.
Figure 1-9. Code generated by the Visual Studio 2005 designer. (Click on the image for a larger picture)
Another important change from Visual Basic 6 is that every form and every control is an instance of a class. When you create a new form with the visual designer, you are defining a new class. But you are not left to implement all the features required for a form yourself. There is an existing class, Form, in the System.Windows.Forms namespace, that provides the base functionality of a form with properties such as Size and BackColor. When you create a new form, you inherit the functionality from the base Form class. The first two lines of LoginForm1.vb (from Figure 1-9) are an example of how you create a class that inherits the functionality of another class.
Public Class LoginForm1 Inherits System.Windows.Forms.Form
When you place a button on a form called btnOK, you are actually creating a field for your specialized form class that will hold a reference to a Button object at runtime. The visual designer also generates code that manipulates the state of that Button control to properly position it on the form, set its caption (that is, its Text property), and so on. When you double-click the Button control in the visual designer to write some code, the designer creates an event handler that is registered with the Click event of btnOK. You can also add your own events and properties to the form class. In fact, anything you can do with a class you can do with a form because a form is a class.
All the details for forms are contained within designer.vb code files. Visual Studio 2005 provides an excellent design environment for creating and editing these designer.vb files visually, so you rarely have to edit the code for the designer files directly.
There is an important difference in how you open a form in Visual Basic .NET. In Visual Basic 6, you create a .frm file such as Form1.frm. The name of the form is Form1, and you open this form by typing Form1.Show. In Visual Studio 2005, the filename is irrelevant. What is important is the name of the class defined in the .vb code file (although typically, the code file and the class do have the same name). Suppose the class name is Form1. If you want to open Form1, you can either execute the Form1.Show, or create an instance of that class and call the Show method of that instance, as shown in the following code block.
Form1.Show() Dim f As New Form1 f.Show()
The .NET Framework changed the Windows development landscape dramatically. Version 2.0 of the .NET Framework introduces new features to make you more productive and give you access to a richer set of functionality when building your Windows applications.
There are a number of new features in Visual Basic 2005, such as options for setting padding within a control (specifically, in the internal margin of a control) and margins around a control. These properties are inherited from the base Control class, so they are available for every type of control. There are new controls and settings for creating user interfaces with the professional look and customization support of products such as Microsoft Office. There are also new panel controls that support flow and table layouts. These and other enhancements are discussed in more detail in later chapters, including Chapter 5, "Constructing User Interfaces."
An extremely useful and popular new R AD feature is snap lines, a feature of the visual form designer in the IDE (rather than a language or Framework Class Library feature). If you have spent much time building user interfaces in Visual Basic 6 or Visual Studio .NET 2003, you know how difficult it can be to properly align controls without resorting to editing property values by hand. The visual designer in Visual Studio 2005 includes new visual alignment guides (snap lines) that help you line up controls both horizontally and vertically when placing them on a form. Figure 1-10 shows an example of the alignment guides helping a developer line up an OK button with some other controls vertically and another button horizontally.
Figure 1-10. Control alignment guides in Visual Studio 2005.
Before the release of Visual Studio .NET, building Web applications with Visual Basic required multiple tools and multiple development languages. Visual Studio .NET introduced a unified development environment and a new Web programming model that allowed Visual Basic programmers to transfer their Windows development skills to Web development. Visual Studio 2005 introduces a number of significant enhancements to Web development using .NET technology.
If this is your first exposure to ASP.NET, welcome to the new world of Web development! ASP.NET is an integral part of the Framework Class Library. ASP.NET provides an object-oriented, event-driven infrastructure for your applications that enables them to be hosted by a Web server so that they can respond to Web requests (that is, serve content to Web browsers). ASP.NET 2.0 is an especially exciting release because of the opportunities for incredible productivity boosts and dramatically reduced lines of code.
ASP.NET 1.0 replaced ASP/COM development, which was cumbersome at best. Classic ASP, as it has come to be known, is difficult to debug and maintain. Everything is interpreted script, so performance is lackluster unless you move intensive processing into COM components. If you do use COM components, you have to use multiple development environments and write in multiple programming languages—usually VBScript and either Visual Basic 6 or C++ for the COM components. Using COM components, of course, requires components to be registered on the Web server, adding a layer of complexity to deployment. And in shared hosting and virtual host environments, you are often not allowed to register COM components at all, leaving many developers with scripting as their only option. And VBScript, as you might know, does not allow for strong typing, which means even simple syntax errors have to be discovered and diagnosed at runtime as the script is interpreted rather being discovered during compilation.
In contrast to ASP, ASP.NET Web applications are compiled to IL, which is then JIT-compiled into native binary code. As with Windows applications, the JIT compilation happens up front and the native code is cached for subsequent reuse. There is a small latency associated for the first Web request as the code is JIT compiled. After the first request, ASP.NET Web applications show an impressive performance benefit over script-based Web technologies. That feature alone is compelling enough to move to ASP.NET, but there are also many other benefits.
ASP.NET provides an object-oriented, event-driven framework for Web applications. Web pages are classes that inherit basic functionality from a base Page class in the same way that a Windows form inherits functionality from the base Form class. When you request a Web page, an instance of the class is loaded in memory, a series of methods are called, and a series of events are raised. You write event handlers for events such as Page.Load and Page.PreRender to inject your own custom logic into the page processing. When the processing is finished, the resulting HTML output is sent to the user.
The processing model of ASP.NET is fundamentally different from ASP. In classic ASP, HTML and script are intermingled and processed sequentially (from top to bottom). Dynamic content is injected using Response.Write statements or render blocks (for example, <%= Now %> displays the current date and time). The resulting HTML and script combination can be difficult to read and hard to debug. By contrast, ASP.NET uses objects, methods, and events to generate output. The result is a better separation of code from content and a richer programming model.
An ASP.NET Web page, or ASPX page, comprises page directives, HTML content, server control tags, and code. Page directives are special ASP.NET instructions for controlling things such as output caching, turning on Option Strict, referencing components, and importing namespaces. Server controls are special markup elements (that is, tags) that map to classes in the Framework Class Library. When an ASPX page is compiled into a class, server controls become fields of that class. Instances of the appropriate control classes are created at runtime, and references to those objects are assigned to the class fields for the various server controls on the page. The object referenced by each field is then asked to produce its HTML output via its Render method. The resulting HTML output from an ASPX page is the HTML output from the page itself plus the HTML output generated by each server control.
Note Output can also be generated in ASP.NET by using Response.Write, but the event driven processing model makes it difficult to use Response.Write unless all content is generated with Response.Write (ASP style), which would negate the benefit of the object-oriented, event driven model.
The following ASPX markup shows a simple Web page that includes a TextBox server control.
<%@ page language="VB" %> <html> <body> <form id="form1" runat="server"> <asp:TextBox ID="txtName" Runat="server" /> </form> </body> </html>
When this Web page is rendered, the TextBox control renders itself as an HTML <input> tag as shown here.
<html> <body> <form method="post" action="Default.aspx" id="form1"> <div style="display:none"> <input type="hidden" name="__VIEWSTATE" value="/wEPDwULLTIwNDAwODk2OTNkZLcvFD+nrIIdGTNg9IaMLK9y8exu" /> </div> <input name="txtName" type="text" id="txtName" /> </form> </body> </html>
One of the great benefits of server controls is that complex behavior can be encapsulated in a server control and then used on a Web page with a single tag. Controls such as Calendar, GridView, and SiteMapPath are all examples of complex server controls that can generate considerable amounts of HTML output but only require a line or two of ASPX markup to use. This concept is of course very familiar to Visual Basic 6 programmers who are used to working with controls that encapsulate complex functionality. For this and other reasons, many Visual Basic 6 programmers have discovered that the level of skill transfer between Windows development and Web development with the .NET Framework is remarkably high.
The ASP.NET programming and processing models are similar to the Windows Forms programming and processing models, making it easier than ever for Windows programmers to also be Web programmers. For example, the Page.Load event is analogous to the Form.Load event in Windows programming. There are, of course, some additional considerations when working with Web pages, but they are not difficult to master. (For example, form-level field values do not survive after a request.) In fact, a Web programmer using Visual Studio 2005 can be quite productive using the same skills used for Windows programming while knowing very little HTML (or even no HTML).
The .NET Framework 2.0 introduces a considerable number of new features for Web applications. There are new Membership and User Profile subsystems that provide significantly enhanced support for managing and authenticating users, doing role-based authorization, and storing user information (for example, address information). There are also new security controls such as the Login and LoginView controls that tie into the new Membership system. With ASP.NET 2.0, you can actually create a Web site with built-in authentication, including a user's database, without writing any code! Just add a few lines of markup and that's it!
New data source controls let you declaratively specify data source settings instead of having to write common data access code. There are also a number of new data controls and enhancements to existing data controls—most notable is the ability to bind a data control to a data source control to create rich, data-driven, zero code Web sites.
There are still more new features in ASP.NET 2.0. You will see more about these enhancements later in this book, particularly in Chapter 6, "Building Web Applications."
There are many good reasons for writing code that targets the .NET Framework, including those mentioned at the beginning of this chapter such as productivity, security, and "deployability." Developers have found that they can write better code faster when they target the .NET Framework and develop with Visual Studio. Visual Studio 2005 is the next step in the evolution of Visual Studio. Visual Studio 2005 and the .NET Framework 2.0 contain many interesting and exciting enhancements that are detailed in the rest of this book. The following sections provide some examples.
Visual Basic Enhancements
There are a number of changes in Visual Basic, including the much-anticipated introduction of Generics, the new Using statement, the new IsNot keyword, and operator overloading. Edit-and-continue debugging is now supported for Visual Basic .NET projects, a feature missed by many former Visual Basic 6 programmers.
The Visual Basic code editor includes additional features, such as symbolic rename, which intelligently renames all occurrences of an identifier (for example, a variable). Also new in Visual Studio 2005 are code snippets, which are blocks of code for common tasks that you can insert into the code editor from the context menu. Visual Studio 2005 includes a number of predefined snippets for common tasks, and you can define your own snippets.
A new feature unique to Visual Basic 2005 is the My namespace, which acts as a wrapper or "speed dial" for common tasks. One of those common tasks is showing a default instance of a form. Instead of explicitly creating a new Form1 variable and instantiating it, you can just call My.Forms.Form1.Show. The My.Forms collection exposes a default instance of each form class in your project. You can even leave off the My.Forms prefix and simply call Form1.Show, giving you the same syntax as Visual Basic 6, although with a very different underlying implementation.
Each successive version of Visual Studio introduces new IDE features to help make you more productive. Just a few of the new IDE features in Visual Studio 2005 are the Exception Helper, new debugger data visualizations for HTML and XML, window docking guides, and syntax error assistance.
The Exception Helper is a new feature that gives you better access to exception details when debugging and provides troubleshooting tips to help you correct your code to avoid fatal exceptions.
There are new visualizations for viewing HTML and XML data in string variables at runtime.
In debug mode, when you hover over a string variable you can choose to view the string as XML or HTML. When you select one of these views, the data is rendered appropriately in a pop-up window.
If you have ever been frustrated trying to reposition windows within the Visual Studio IDE, you will love the new docking guides that make it easy to dock a window exactly where you want it.
The Visual Studio IDE has long provided design-time syntax checking for your code. Visual Studio 2005 enhances that design-time experience with new syntax error assistance that not only identifies the syntax error but provides suggestions for correcting the error based on what your code appears to be intended to do.
These new IDE features and more are covered in Chapter 3, "Visual Studio 2005 Integrated Development Environment."
New Visual Web Developer
Visual Studio 2005 includes a completely revamped Web development tool called the Visual Web Developer. Although some of the improvements over Visual Studio .NET 2003 will not be immediately evident, many become quickly apparent. One of the noticeable changes is that the designer does not reformat your markup on you when you switch between design and markup views of your Web pages.
The new Visual Web Developer in Visual Studio 2005 includes a new lightweight Web server that listens for requests on an arbitrary port (for localhost only) when you run your Web applications. Figure 1-11 shows an example of a Web page being served by the built-in Web server. The Visual Web Developer Web Server is meant for development purposes only. It allows developers to create and test ASP.NET Web applications without requiring IIS (Internet Information Services). It also makes it easier for Web developers to work without elevated permissions (for example, running as Domain User instead of local Administrator) because rights are not needed for administering IIS or debugging other users' processes.
Figure 1-11. Visual Web Developer Web Server running on port 22289. (Click on the image for a larger picture)
The difficulties associated with deploying Windows applications in the past have driven many organizations toward Web applications for the sake of simplified deployment. This leaves computing resources on the edge of the network underutilized and constrains applications to a very limited user interface. Although the .NET Framework 1.1 solves some of the problems of deployment, such as DLL versioning conflicts, and makes possible a Web-based deployment strategy known as "No-Touch" deployment, there is room for improvement. The new ClickOnce deployment features in the .NET Framework 2.0 make it easy to deploy self-updating Windows or console applications that do not require administrative rights to install and can run in an offline mode.
For more details on how ClickOnce deployment works, see Chapter 8, "Deploying Applications."
The Microsoft .NET Framework provides a managed environment for running many types of applications. The .NET Framework is a platform for Windows, Web, console, and smart device applications. Services provided by the .NET Framework include object lifetime management (also known as garbage collection), security, type safety, and interoperability with COM. The .NET Framework also provides a rich class library that you can use to reduce the amount of code you have to write (and therefore test and maintain). This results in better productivity and safer code because the class library has already been field-tested on computers around the world.
The .NET Framework has brought about a radical shift in the way developers build software. The services provided by the Common Language Runtime and the functionality provided in the Framework Class Library take care of a lot of the plumbing and utility type of programming that can be so time-consuming. By targeting the .NET Framework, developers are able to spend more time solving their domain-specific problems instead of solving generic problems such as how to pass messages between a client application and a server (Web services).
The rest of this book introduces Visual Studio 2005, the latest version of the premiere development tool for targeting the .NET Framework. You will see many of the improvements made to the .NET Framework in version 2.0 and the new features in Visual Studio 2005 that will help make you a more productive developer.