.NET for Visual FoxPro Developers
Every six or seven years Microsoft makes a quantum leap in
technology. In February
of 2002 that quantum leap was .NET. What is .NET and what does it mean for Visual FoxPro developers? This chapter provides an overview of .NET, the .NET Framework and languages, and explains why you should investigate .NET for your software development projects.
.NET burst on to the software development scene with lots of fanfare and plenty of marketing from Microsoft. In many ways .NET is a departure from previous Microsoft technologies; in other areas the change is more evolution than revolution.
Although there is a brand new .NET language, C#, a completely revamped Visual Basic .NET, and dozens of .NET ports of other languages including COBOL, Visual FoxPro is not a .NET language and Microsoft has told us that it never will be. What does this mean for you, as a Visual FoxPro developer? Why, when, and where should you use .NET technologies? This chapter aims to help you answer these questions.
What is .NET?
Originally, Microsoft pitched .NET as, “a platform for building, deploying, running, integrating, and consuming Web services”. The result was most people thought you could only use .NET to build Web applications. In addition, because Web services were slow to catch on, it caused a number of developers to take a wait-and-see approach. You can compare this to marketing Visual FoxPro only for its Web services capabilities—although you can build Web services with VFP, it is certainly not its primary function.
After several months Microsoft recognized its marketing error
and in August of 2002, Bill Gates provided an updated definition of .NET: “.NET
is software to connect information, people, systems, and devices.” I think this
message is better, but I’m not sure it’s clear or specific enough. I think a
better explanation—at least from a developer’s perspective—is
that .NET is Microsoft’s new programming model for building desktop, mobile, and Web-based applications.
What is the .NET Framework?
When most people refer to “.NET”, they’re usually referring to the .NET Framework. The .NET Framework is really three things:
· A library of unified core classes that provide the plumbing for applications.
· Presentation classes for developing ASP.NET and Windows Forms applications
· The Common Language Runtime (CLR), an environment in which your .NET programs are executed.
The .NET Framework class library
Before the arrival of .NET, the Windows API was the primary way you accessed services of the Windows operating system. The Windows API was developed over a number of years and can be a confusing morass of functions that are difficult to learn and use. In contrast, the .NET Framework provides a set of classes with properties, events, and methods you can use to access these same services in a far more logical, intuitive manner.
For example, the .NET Framework has an Environment class you can use to get and set information for the environment and platform on which your application is running. The following properties found in the Environment class are intuitive and self-descriptive:
You don’t have to be a rocket scientist to figure out what the following methods of the Environment class do for you:
This is far easier than trying to find and learn how to use Windows API functions that give you the same information.
That said, the biggest learning curve for .NET is the .NET Framework classes. Here’s a comparison for you—Visual FoxPro has 35 different base classes you can use in your applications, including text boxes, combo boxes, grids, containers, custom classes, sessions, and so on. In contrast, the .NET Framework has over 2000 base classes! Figuring out what classes are available to you and which to use in a particular situation is where most of your learning curve will be.
However, to truly make a fair comparison between Visual FoxPro and the .NET Framework classes, you need to remember that there are over 500 functions, approximately 430 commands, and over 75 system variables that comprise the VFP language. In comparison, the organization of the .NET Framework classes makes it easier to find the functionality you need. For example, in Visual FoxPro, there are a few dozen commands you can use for string manipulation. When you were first learning Visual FoxPro, it probably took you a while to discover all of these commands (and maybe you haven’t found them all yet!).
In contrast, .NET implements all of these string manipulation capabilities as individual methods of the String class. Once you discover the String class, you have all of this string manipulation functionality at your fingertips. You will find this holds true for all different types of functionality in the .NET Framework classes.
The Common Language Runtime
The Common Language Runtime performs a similar function as Visual FoxPro’s runtime with a few key differences. Visual FoxPro is an interpreted language; executables are stored in pseudo-code (p-code) format. When it is executed, p-code is translated into machine code by the Visual FoxPro runtime (Figure 1).
In .NET, code is compiled twice—first into MS Intermediate Language (MSIL) by the compiler on your development machine and again at runtime when the code is executed by the CLR. As shown in Figure 2, regardless of the language in which the source code is written, whether it’s C#, Visual Basic .NET or C++, it’s compiled into the same intermediate language. Typically, it’s this intermediate language that is distributed to your end users.
When MSIL is executed on the end user’s machine, it is compiled again into machine code by a .NET Just-In-Time (JIT) compiler. The benefit of this approach is that CPU-specific JIT compilers can be used to compile the MSIL code into machine code that takes advantage of the specific processor on your end-user’s machine. So, if the MSIL code is compiled on a machine with a newer processor and more advanced capabilities, the JIT compiler can take advantage of these.
The JIT compiler only compiles code that is to be executed. The resulting executable code is cached until the application is exited, so it does not need to be recompiled when the same code is executed again. This is different than Visual FoxPro where p-code is interpreted to machine code when it’s run (and does not produce machine code that is cached as in .NET).
Why .NET for VFP developers?
Visual FoxPro is a great development tool for building desktop applications, Web applications, and Web services. So, why should VFP developers be interested in learning and using .NET? This section provides a number of reasons I find most compelling.
You are probably aware that the number of new Visual
FoxPro projects comprises a
relatively small percentage of the total number of software systems being created. In contrast, the need for .NET developers is on the rise and will continue to increase over time. Having both a Visual FoxPro and .NET skill set can only improve your marketability as an employee or consultant.
If you do nothing else with .NET, you may be interested in creating Web applications using ASP.NET. Microsoft has put a lot of energy into ASP.NET making it much better than its predecessor, ASP. Rather than using scripting languages to create Web applications, you can use a fully object-oriented .NET language such as C# or VB .NET.
If you learn how to create .NET Windows Forms applications using Visual Studio .NET, you can use the same set of skills and familiar IDE to create Web Forms applications and XML Web services, greatly reducing your learning curve.
Building middle-tier components
Visual FoxPro is a great tool for building middle-tier
components based on its data access
and string manipulation speed (which is great for XML). However, Visual FoxPro components are COM (Component Object Model) based. After several years of working with COM components, I can tell you that they are a royal pain in the neck! Here are my “three strikes” against VFP COM components:
1. They’re a pain to debug. To figure out what’s going on inside of a COM component, you typically have to use STRTOFILE() to output the value of variables to a text file in order to determine why a COM component isn’t working. This is enough to make a grown man cry.
2. They take you to DLL hell and back again. First of all, COM DLLs must be registered in the Windows Registry, and sometimes (for reasons unknown) the registration process just doesn’t work. It also means that if you have multiple versions of the same DLL on a single machine you can run into versioning problems.
3. You can’t take advantage of COM+ object pooling because of Visual FoxPro’s threading model—this is also true of Visual Basic 6. Object pooling allows COM+ to recycle or reuse middle-tier components. When a middle-tier object releases itself, COM+ places it in an object pool so other clients can reuse it. Note that COM+ is still the technology used to host middle tier components—even .NET components!
.NET addresses each of these issues:
You can easily debug .NET components with Visual Studio
.NET. In fact, the debugger allows you to step through code written in any .NET
example, you can step through client code written in VB .NET that calls a method
in a C# component.
2. .NET component DLLs are self-describing and do not need to be registered in the Windows Registry. Typically, all you need to do is copy a .NET DLL to a machine and it just works!
3. .NET components can be hosted in the COM+ environment and can be pooled.
In many large software development shops, multiple languages are used by different teams of developers. .NET offers language interoperability at a whole new level. You can create classes in one .NET language and subclass them in another .NET language. You can also work with different languages within the same Visual Studio .NET IDE.
Interestingly, other vendors (besides Microsoft) are creating .NET versions of older programming languages such as COBOL, PERL, Eiffel, and Smalltalk among others.
Abstracting operating system services
As mentioned previously, the .NET Framework class library provides object-oriented access to services of the underlying operating system. This is far superior to making calls to the Windows API, because calls to the Windows API assume that you are running on the Window operating system!
Making calls to the .NET Framework class library adds a layer of abstraction that can eventually allow your code to be moved to non-Windows machines running on different hardware platforms such as wireless and handheld devices.
One of the limitations in Visual FoxPro is the inability to created multi-threaded applications. If this capability is important to you, then .NET makes it easy to create multiple threads of execution, allowing your applications to perform background tasks, such as printing, performing calculations, and sending or retrieving e-mail.
You’re in a great position to learn .NET
If you’ve already climbed the Visual FoxPro learning curve, you’re in a great position to learn .NET—much more so than Visual Basic developers. This is because the biggest learning curve for VB developers moving to .NET is object-orientation. Although VB 6 was object-based, it did not have true implementation inheritance (see Chapter 5, “Object-Orientation in C# and Visual Basic .NET” for details). In comparison, it’s a much shorter learning curve for Visual FoxPro developers to learn the syntax of C# or VB .NET.
From the perspective of .NET there are two kinds of code in the world, managed and unmanaged code.
Managed code is executed and managed by the common language runtime. Managed code contains metadata that provides information that allows the runtime to provide services such as memory management, security, and garbage collection. All MSIL code is managed code. For more information on metadata, see the “Manifests” section later in this chapter. For more information on garbage collection, see the section “Garbage collection” in Chapter 5, “Object Orientation in C# and Visual Basic .NET”.
Unmanaged code is any code that runs outside of .NET. This includes Visual FoxPro code located in COM servers (Figure 3).
Unsafe code is different than unmanaged code. For information about unsafe code, see Chapter 3, “Introduction to C#”.
In Visual FoxPro, depending on the type of project you compile, the resulting code is stored in an APP, EXE, or DLL file. In .NET, Windows Forms and Console projects are compiled into EXE files that contain MSIL; Web Forms, Web Services and Class Library projects (including Windows Control libraries) are compiled into DLLs that contain MSIL. The resulting EXE and DLL files are referred to as assemblies.
An assembly is the primary building block of a .NET application. The term assembly is a logical rather than physical designation because, although an assembly is usually comprised of a single file, it can also be comprised of one or more files (Figure 4).
Multi-file assemblies allow you to break up an assembly into smaller units that are easier to maintain and are a smaller size for downloading. It also allows you to create a single assembly that is comprised of components built in multiple languages.
An assembly is self-describing—it does not have to be registered in the Windows Registry because it possesses a manifest that contains metadata about the assembly.
An assembly’s manifest contains information such as the assembly’s identity (name, version, and culture), a list of all the files in the assembly, information about all referenced assemblies, and details of all classes and their members.
A great way to examine an assembly manifest is to use the .NET IL Disassembler tool. The IL Disassembler (ildasm.exe) is found in the FrameworkSDK\Bin folder below the directory on your machine that contains the .NET Framework. To launch this program you can simply double-click on it in Windows Explorer. To open up an assembly for viewing, select File | Open from the menu, and select a .NET assembly. The Disassembler displays the assembly manifest as well as any namespaces declared within the assembly (Figure 5). For more information on namespaces, see the “Namespaces” section later in this chapter.
If you expand a namespace node, it displays all of the classes in the assembly that belong to the namespace. Figure 6 shows a list of the different icons used within the disassembler and a description of how they are used. You can find this list in the help for the disassembler tool. For a detailed description of each of these elements (such as class, interface, method, static method, and so on) see Chapter 5, “Object Orientation in C# and Visual Basic .NET”.
If you double-click the Manifest node in the disassembler tree view it opens a sub-window that allows you to view the assembly’s manifest. Depending on the assembly you open, at the top of the window, you may see a list of external assemblies that are referenced by the assembly (for example: “assembly extern System.Windows.Forms”). The first assembly reference you see that does not have the “extern” keyword denotes the beginning of the manifest’s “identity” section. This first entry in the identity section of the manifest specifies the name of the assembly. The identity section also contains the version number of the assembly. The version number is denoted by the “.ver” directive.
Probably the coolest feature of the IL Disassembler is the ability to view MSIL code. If you double-click on a class method, it opens up a window displaying the MSIL code. If you want to see both the source code and the IL code in this window (Figure 7), select View | Source Lines from the IL Disassembler menu. For most developers, viewing the IL code falls under the category of “cool things you can do”, versus providing any practical benefits.
Private and shared assemblies
There are two types of .NET assemblies, private and shared. A private assembly is used by only one application. The assembly is stored in the application’s folder. This makes it easy to install an application—all you have to do is copy the files to the appropriate folder. You can also store an assembly in an application subfolder, you just need to give the subfolder the same name as the assembly it contains. For example, if you have an assembly named “MyLibrary”, you can place it in a subfolder named “MyLibrary” below the application folder. This allows you to segregate your external assemblies from your project files.
A shared assembly is used by more than one application. Shared assemblies are stored in a special directory known as the Global Assembly Cache (GAC). By default, this directory is c:\winnt\assembly or c:\windows\assembly. An example of shared assemblies is the .NET Framework. All .NET applications need access to the .NET Framework’s assemblies, so these are located in the Global Assembly Cache.
Viewing assemblies in the Global Assembly Cache
When you install the .NET Platform SDK on your computer, it automatically loads a Windows shell extension called the Assembly Cache Viewer that allows you to view the Global Assembly Cache from within Windows Explorer. All you have to do is use Windows Explorer to navigate to the <windows directory>\assembly folder and you see assemblies displayed in the right pane (Figure 8).
For more information on creating and installing shared assemblies, see the section “Creating and installing shared assemblies” in Chapter 2, “Visual Studio .NET”.
In .NET, the primary way you avoid duplicate class names is by means of namespaces. A namespace is a naming mechanism that allows you to declare logical categories for your classes. For example, in the .NET Framework, there are namespaces such as:
At first, many Visual FoxPro developers equate namespaces with class libraries, but they’re really quite different. A VFP class library is a physical container that holds one or more classes. A .NET namespace has nothing to do with the physical location of a class—it is purely a logical name used to categorize a class.
The parts of a namespace typically go (from left to right)
general to more specific.
This is similar in concept to the taxonomies of living things. For example, Figure 9 shows
the taxonomic hierarchy of the red fox. From kingdom, to phylum to subphylum to class, and so on, each level moves from general to specific. This convention allows all living things to
Microsoft has suggested that you declare your namespaces as follows: the first part of a namespace should be your company name, the second part should be your product, the third part should specify a category of classes, and so on. For example, I have declared a namespace to which all of my company’s business objects belong as “OakLeaf.MM.Business”. Oak Leaf is my company name, MM is the product name (Mere Mortals Framework), and Business specifies business object classes.
For information on assigning classes to a namespace, see Chapter 3, “Introduction to C#” and Chapter 4, “Introduction to Visual Basic .NET”.
.NET Programming Languages
As of this writing, there are three main .NET languages from which you can choose: Visual Basic .NET, Visual C# .NET, and Visual C++ .NET. Since the vast majority of Visual FoxPro developers using .NET will choose either Visual Basic .NET or C# as their software development language, this book concentrates on these two languages, providing examples in each and information that can help you decide which language is right for you.
Visual C# .NET
Although “Visual C# .NET” is the “official” name of the language, you almost always see it referred to as simply “C#” (pronounced C sharp), and this is the convention I use in this book.
C# is a brand new computer language written specifically for .NET and it has generated a lot of excitement. In fact, Microsoft used it to create the .NET Framework base classes. As of the writing of this book, many Visual FoxPro developers learning .NET have chosen C# as their programming language of choice.
Because C# is in the “C” family of languages, its syntax is similar to C++, but it is most similar to Java. C# can also be used to create Windows Forms applications, Web Form applications, XML Web services, console applications, class libraries, and more. C# is designed to combine the power and control of C and C++ with the ease of use often associated with Visual Basic for high productivity. For details on C#, see Chapter 3, “Introducing C#”.
Visual Basic .NET
Visual Basic .NET is the newest version of Microsoft’s Visual Basic programming language. The difference between VB .NET and Visual Basic 6 is as big as the difference between FoxPro 2.6 and Visual FoxPro—and then some.
Unlike its predecessor, Visual Basic 6, VB .NET is a fully object-oriented language that was completely rewritten for the .NET Framework. You can use VB .NET to create Windows Forms applications, Web Form applications, XML Web services, console applications, class libraries, and more. In its new incarnation VB .NET also continues its role as the “glue” that fills in the gaps and binds applications together. You can use Visual Basic .NET to create macros for use in the Visual Studio .NET IDE.
As you might expect, VB .NET has some nice convenience features and you will probably continue to get more of these in subsequent versions of .NET.
For details on Visual Basic .NET, see Chapter 4, “Introducing Visual Basic .NET”.
Microsoft has come up with a list of naming guidelines for .NET languages. Their hope is to have most developers jump on board with these conventions so everyone can read each other’s code more easily. One guideline that has surprised many developers is the recommendation to discontinue the use of Hungarian notation.
The official naming guidelines can be found on the Web at:
Overview of the development process
It’s appropriate in this chapter to give you a high level overview of the development process when creating a .NET application. Seeing the big picture can hopefully place each chapter in this book in the context of the development process.
Before you write one line of code, you should gather requirements for the application. Most software development shops these days use the Unified Modeling Language (UML) and the Rational Unified Process (RUP) for this purpose. Microsoft has recognized the importance of analysis and design by adding UML diagrams to their Visio diagramming tool and integrating Visio with Visual Studio .NET.
In this section I’m using UML terminology that may not be familiar to you. To learn more about the Unified Modeling Language, check out books such as The Unified Modeling Language User Guide from Addison-Wesley.
The first step in gathering requirements involves documenting how the end user will use the software system. This is primarily achieved by means of UML use case diagrams.
Building a plan for construction
After gathering your requirements, you should build a plan for construction. This includes determining how long the entire project will take to complete and choosing which parts of the application to build first, second, and so on. When using the UML, you select use cases to be further analyzed, designed, and implemented.
Designing and building business objects
During construction you further analyze your use cases and design business objects that carry out the logic of each use case. This means adding methods to business object classes that will contain the majority of your application logic. This approach is very different from the way most Visual FoxPro developers create applications today—they place the majority of application logic in the user interface. However, using business objects makes your applications far more flexible, scaleable, and maintainable.
Typically, you should create a Class Library project in either C# or VB .NET to contain your business objects. This project can be compiled into an assembly that can be referenced from a variety of applications (Windows Forms, Web Forms, Web Services, and so on).
For more information on designing and implementing business objects, see Chapter 8, “.NET Business Objects”.
As you design your business objects, you should also start thinking about modeling your application data. Even if I’m designing an application to work with client server data, I often find creating prototype tables in Visual FoxPro is a great “proof-of-concept” technique. Because FoxPro developers tend to see the world in terms of data, placing data in tables can help work out any kinks in the object model that may otherwise go undetected.
Ultimately, before you actually create business object classes in your language of choice, you should finish modeling the associated data.
For more information on accessing data from within a .NET application, see Chapter 7, “Data Access with ADO.NET”.
Building the user interface
If you’re creating either a Windows Forms or Web Forms application, you need to design and build a user interface. You can create a new Windows Forms or Web Forms application using Visual Studio .NET and add a reference to your business object library to the project so these classes are accessible from your user interface.
As mentioned previously, you should not place your application logic in your user interface. Think of your user interface as the “skin” of your application, which can easily be replaced with an alternate skin.
You can place code in your user interface that instantiates business object classes and calls their methods to perform services such as retrieving data, manipulating and saving data, performing calculations, and so on.
For information on building your application’s user interface, see Chapter 9, “Building .NET WinForm Applications”, and Chapter 10, “Building Web Applications with ASP.NET”.
Building an XML Web service
If you are creating an XML Web service, you can create
a new Web services project in
Visual Studio .NET. Afterwards, you can add a reference to your business object library to
the Web services project so these classes are accessible from the Web service.
For more information on building an XML Web Service, see Chapter
Microsoft is betting the farm on .NET. They’ve thrown a
tremendous amount of resources
at .NET and have come up with some very impressive technologies. It is a huge shift
in technology that has evoked the full spectrum of emotions from a wide variety of
people—including Visual FoxPro developers. The rest of this book will help you make informed decisions about .NET—why, when, and where you should implement it in your software development.