VB.NET
VB.NET
NET
Overview
Objectives
This module introduces the new version of Microsoft
Visual Basic. It was redesigned from the ground up to
integrate into the Microsoft .NET Framework. With the
addition of advanced features, Visual Basic.NET is now a
complete object-oriented development tool.
This module assumes you have at least some working
knowledge of earlier versions of Visual Basic. This module
presents the new language features of Visual Basic and
its positioning within the .NET Framework.
What You Will Learn
Overview of the new features
Framework services
Recommended Reading
MacKinsey, Duncan. Teach Yourself Visual Basic.NET
in 21 Days. Indianapolis, IN: Sams, 2001.
Hollis, Billy, and Rockford Lhotka. VB.NET
Programming with the Public Beta. Birmingham, UK:
Wrox Press, 2001.
Section 1: Overview
Section 1: Overview
Make the language even easier to use
Visual Basic has been the most widely used language on
the Microsoft Windows platform since it was introduced.
And the advent of Visual Basic 4 with its support for OLE
2.0 and particularly Automation made it even more
successful.
However, Microsoft and hence the Windows platform is
shifting from a mere desktop operating system to a more
Web serviceoriented system. This shift recognizes the
reality that applications are beginning to migrate from a
standalone executable sitting on a user's hard drive to a
distributed application delivered by a Web server across
the Internet. A key part of Microsoft's thrust into this new
Web services space is the .NET Framework. The .NET
Framework is designed from the ground up to allow
developers to easily write and deploy complex Web
applications.
Visual Basic 6 has a lot of ties to its ancestor GW Basic.
New features were added over time that did not conserve
the original style. So there were a lot of inconsistencies
and backward-compatibility issues that prevented Visual
Basic from becoming a well-structured language. Since
the integration into .NET required some changes, this was
the right time to get rid of the major problems. That does
not mean that Visual Basic is now just another language
like C++. The main reason for using Visual Basic used to
be its simplicity in terms of hiding all the dirty details of
system programming, and this reason is still alive.
Section 1: Overview
Section 1: Overview
Inheritance Concepts
Concept of Reuse
One form of reuse of the implementation effort to build a
component or a class can be to include the component as
a member within the new class or component. Tasks that
can be fulfilled by the included class are then delegated to
it.
By inheriting a class, the new derived class automatically
supports all features of the base class. No further action
like delegator functions are required.
Building Type Hierarchies
Inheritance allows not only for some selected
relationships but also for extensive hierarchies of types.
This possibility can be a blessing or a curse. One has to
be careful when constructing these hierarchies. You
should use inheritance relationships when the relationship
is close and can be expected to stay close; otherwise use
the composition scheme.
Versioning
When building a new version of a component, inheriting
from the old version is a convenient way to keep all
existing contracts and modify or add only as much as
necessary. The new component will serve as a full
substitute for the old because an instance of a derived
class will work anywhere an instance of the base class
was required. This is known as polymorphism.
Polymorphism
The traditional way to use polymorphism in Visual Basic
was with interfaces. Interfaces can still be used for this
purpose, but you now have the option of using inheritance
Section 1: Overview
Interfaces
Declare semantic contracts between parties
Interfaces describe a set of properties and methods and
events. Interfaces are a way for you to define protocols
they represent a contract that the implementer of the
protocol agrees to.
Define structure and semantics for specific purpose
By defining features in terms of interfaces composed of
small groups of closely related functions, you can
implement component features as needed, knowing that
you can expand them later by implementing additional
interfaces.
Abstract definitions of methods and properties
Unlike classes, interfaces do not provide implementations.
They are solely abstract definitions.
Support (multiple) inheritance
Interfaces can be inherited to classes directly or to other
interfaces. Maintaining compatibility is simplified, because
new versions of a component can continue to provide
existing interfaces while you add new or enhanced
interfaces.
Classes can inherit from a single base class, but from
multiple interfaces. Because of this, the functionality of a
class can be constructed from building blocks, each
dealing with a separate field of operation.
10
Language Features
Type System
Types can describe values and objects. When they are
associated with a value, they describe how the binary
representation of that value is to be interpreted.
Objects have rather more to them than do values. In this
case, types describe the contract that the object has to
fulfill.
Each object is self-typing, that is, its type is explicitly
stored in its representation. It has an identity that
distinguishes it from all other objects, and it has slots that
store other entities (which may be either objects or
values). While the contents of its slots may be changed,
the identity of an object never changes.
Classes and Inheritance
A class is the type of an object. These types can have
inheritance relationships. Since this is a completely new
concept to Visual Basic, we will explore this matter in
depth.
Exception Handling
Since it is necessary to deal with run-time errors that
cannot be avoided altogether, the language offers some
features to deal with these error conditions in a graceful
way, that is, without crashing the application.
Event Concept
Events are not a new concept to Visual Basic, but
because the event model is now based on the .NET
Frameworks intrinsic event model, we give a brief
description of the new features here.
11
Changes
This new version of Visual Basic does not just add new
features. Mainly because of the integration into the .NET
Framework, some changes became necessary in addition
to a long-expected review and redesign of certain
inconsistencies and irregularities within the language.
12
Type System
Uses the .NET common type system
The underlying .NET type system is one pillar of the
interoperability of .NET. Common types in all supported
languages ensure that the instances of these values and
objects are easily interchangeable.
Every type is either a value or a reference type
With one exception, types in the .NET Framework are
divided into two categories: value types and reference
types. Enumerated, structure, and the primitive types are
value types. Class types, standard module types, interface
types, array types, and delegate types are reference
types. The root type Object, which is an alias for
System.Object, is special in that it is a reference type that
also can contain a value type. The value type is then
wrapped by a reference and said to be boxed.
13
Primitive Types
Integral types
Visual Basic.NET supports integer number types ranging
from 8 to 64 bits.
The Byte types are 8 bits wide, and Short types hold 16
bits, while the Integer type holds 32 bits.
Unlike C/C++, the Long type in Visual Basic.NET is
always 64 bits wide, providing an ample value range for
almost any usage scenario.
Floating-point types
There are two different floating-point types: Single, which
is a 4-byte numeric value, and Double, which is an 8-byte
value. Both types are IEEE compatible and are identical
with the Framework types System.Single and
System.Double, respectively.
Exact numeric type
For exact calculation there is a numeric type Decimal,
which can hold 28 digits. This type replaces the Currency
type, which was less accurate and less flexible.
Boolean, Date, Char
The Boolean type represents one of the two states true
or false. A Boolean variable can be set via the keywords
True and False or from the outcome of an expression.
When other numeric types are converted to Boolean
values, 0 becomes False and all other values become
True. When Boolean values are converted to other data
types, False becomes 0 and True becomes 1.
14
15
Enumerations
Symbolic name for a set of values
An enumeration (Enum) is a special form of value type,
which inherits from System.Enum and supplies an
alternate name for an underlying primitive type. An Enum
type has a name, an underlying type, and a set of fields.
The fields are static literal fields, each of which represents
a constant. Each field is assigned a specific value of the
underlying type by the language compiler. Multiple fields
can be assigned the same value. When this occurs, the
compiler marks exactly one of the Enum values as a
primary Enum value for the value, for the purposes of
reflection and string conversion.
Strongly typed
Enumerations are always strongly typed
interchangeable with integer number types.
and
not
16
Arrays
Built on .NET System.Array class
All arrays declared in Visual Basic.NET are based on
the .NET Frameworks System.Array class and thus have
all of its capabilities, such as sorting and searching.
Declared with type and shape
When an array is declared, the underlying type and rank
must be specified.
Declaration only syntax
Because arrays in Visual Basic.NET are indeed objects
and reference types, they do not require their bounds to
be specified at declaration time.
Lower bound is always zero
Arrays in Visual Basic.NET are strongly typed and zero
based. This means that the first element of each
dimension in the array can be found at the index position
0 with the upper index at n1 if the array capacity is n.
Fixed size no longer supported
In Visual Basic 6.0, you can specify the size of an array in
its declaration, as in the following example:
Dim Month(0 To 11) As Integer
17
Classes
Concept for objects: data and code
Classes are the core concept for object-oriented
applications. A class groups data and all code that
handles this data into a tightly coupled unit.
Classes contain members
Classes may contain the following elements:
to all instances
have different
properties and
Properties and
of a class,
values for
fields are
fields that
18
19
Inheritance (1/2)
Single base class, but multiple base interfaces
Classes can inherit from a single base class only. Classes
and structures can implement an arbitrary number of
interfaces.
Abstract base classes
Abstract classes can only serve as a base for other
classesthey cannot be instantiated. Declaring a class
with the modifier MustInherit marks this class as abstract.
To use the functionality of this class, you must declare a
class inheriting from the abstract base class and
instantiate this derived class. You do not need to add or
modify functionality.
Non-inheritable classes
Under certain circumstances it can be useful to prohibit
using a class as a base class. That can be achieved by
declaring the class as NotInheritable.
20
Inheritance (2/2)
Overloads
Overloading a procedure means defining it in multiple
versions, using the same name but different signatures,
that is, with the same name, but different parameter types,
count, or order. The purpose of overloading is to define
several closely related versions of a procedure without
having to differentiate them by name.
You can overload a Function with a Sub, and the other
way around, provided they have different argument lists.
You can overload properties the same way as Functions
and Subs, given that they use parameters, since
otherwise they would have the same signature.
Overridable, Overrides
To allow overriding of a member property or method, you
must declare it with the keyword Overridable. To actually
override a method or property in the derived class, the
member must be explicitly declared with the keyword
Overrides. These provisions make sure that no accidental
override can occur.
NotOverridable, MustOverride
To prevent a property or method from being overridden, it
can be declared with the keyword NotOverridable. Public
members are NotOverridable by default.
Public member variables cannot be overridden. Private
member variables can be overridden without any
declaration.
21
Qualified access
To differentiate between the members defined in the class
itself or in the base class, qualifiers are provided:
MyClass addresses members declared in the class;
MyBase addresses inherited members. There is no direct
way to address members, which are overridden multiple
times in a type hierarchy. You have to provide access
functions for this purposeor better, reconsider your
hierarchy.
22
23
24
Structures
User-defined typesreplaces Type
Visual Basic considers structures and user-defined types
to be the same type of programming element. Visual
Basic.NET updates the structure declaration for unification
and improved readability.
In Visual Basic.NET, the Type statement is not supported.
You must declare structures using the Structure End
Structure construction. This implies no restriction at all,
since the semantics of the Structure type are a superset
of Types semantics.
Lightweight Classes"
Structures are somewhat like lightweight classes. In fact
their definition and usage is almost identical. Structures
are value types and serve to provide a container for very
lightweight, small groups of data that come along with
some handling code.
Good examples for this are points representing
coordinates in a graphics system. In such a system,
points have to be managed and kept in great numbers.
Keeping every single point as a reference type that needs
to be individually tracked by the system for memory
management and maintaining identity would dramatically
reduce the systems overall performance.
The role differences between classes and structures are
therefore:
25
Classes are used for rich objects with their own identity
(by reference) that need to be handled by consumers
and containers.
Structures cannot use inheritance. They can neither
inherit from other structures or classes nor can they be
inherited.
26
Accessibility
Each member can have its own accessibility
Each member of a class or structure can have its distinct
accessibility assigned. The accessibility determines in
which context a member can be invoked.
Private
A member declared Private can be accessed within the
scope of the declaration. That can be a class or structure,
but also a module level.
Protected
Protected members of a class are accessible from within
the scope of the class itself and from derived classes.
Since derivation is not allowed with structures, this does
not apply to them.
Friend
Friend members are accessible from within the assembly
where the declaration is placed. An assembly is somewhat
like a library and is explained later.
Protected Friend
This is a combination of the two: Friend access and
Protected access. This can be useful, since a derived
class must not reside within the same assembly.
Public
No restrictions are imposed on a Public member.
27
Properties
Not a storage locationcan be computed
Properties are a mix between data members and
methods. For any consumer (or client) or the classs
instances, properties look and feel much like data
members in that they can be accessed in very much the
same way.
Usage like data members
You assign values to them and can retrieve values for
them by just specifying their name in an expression.
Inside the class, though, properties are implemented
using a pair of Get and Set methods.
The Get method must return a value of the propertys
type, while the Set method has an implicit parameter
value through which it receives the value the caller
wishes to assign to the property.
Inside both methods, the code may be written in any
shape or fashion.
If you wish to make a property read-only, declare it
ReadOnly and omit the Set method. Similarly, if you want
to make a property write-only, declare it WriteOnly and
omit the Get method.
Can be indexed
Properties can be indexed by parameters. This can be
used as a grouping of properties or additional information
how to compute or store the value.
28
Exception Handling
Exceptions are not necessarily errors
Exception handling deals with unforeseen or foreseen
conditions under which the main flow of control cannot be
continued. These conditions might be that a file cannot be
opened due to certain circumstances, a number cannot be
computed because of an overflow error, or other run-time
errors. It is not possible to check for all possible errors
before starting an action: some checked conditions may
not hold true while the action lasts.
Some of these conditions are not really errors: they can
also be a planned or expected outcome of a certain
function.
It is good practice to prepare for such conditions. Visual
Basic.NET provides the programmer with two different
styles to declare how to continue after the error condition
occurs.
Two styles: structured (SEH) and unstructured (UEH)
Visual Basic.NET retains the old On Error style of
exception handling and introduces a structured approach
to the language. This structured exception handling is
already known to people familiar with languages like C++
or Java.
Only one style allowed in a method
In a method only the structured or the unstructured
approach is allowed.
UEH supported for backwards compatibility
As already stated, the On Error keyword is still supported.
This method works a lot like a GoTo. The main issue is
29
30
31
32
Delegates
Object-oriented function pointers
Delegates are objects that serve the same purpose as
function pointers in C++. Because they are type-safe,
secure, managed objects, you get all of the advantages of
pointers without any of their disadvantages. For example,
delegates always point to a valid object and cannot
corrupt memory of other objects. Besides their use as the
equivalent of function pointers, delegates are also used
for event handling and callbacks in the .NET Framework.
Can point to a specific method of a specific instance
Each instance of a delegate forwards calls to one of the
following destinations: a static method, a shared method
of a class, or a public method on a particular instance of
an object. The object and method are defined with the
AddressOf operator when the delegate instance is
constructed. Therefore, the definition of a delegate is
simply the signature of the method to which it forwards its
calls. The implementations of the methods on a delegate
are provided by the runtime, not by user code. Developers
cannot specify additional members on a delegate.
The definition of delegates is accomplished by a special
syntax. They are not defined like regular classes, derived
from System.Delegate, but rather declared by using the
keyword Delegate.
33
Events
Traditional WithEvents style still supported
Visual Basic has supported events for a long time, and the
traditional ways of defining and using events can still be
used. For an object to be able to use event handling, it is
sufficient to declare it using the WithEvents clause. The
event handler now is hooked up to the event using the
new Handles clause. The name of the routine is not
important, and you can hook up the routine to multiple
events.
However, Visual Basic.NET includes several new ways of
working with events that let you dynamically connect or
disconnect events and event handlers.
Event system based on the .NET Framework
An event is an action to which you can respond, or
"handle," in code. Events can be generated by a user
action, such as clicking the mouse or pressing a key, by
program code, or by the system.
Implemented on top of delegates
The .NET event model uses delegates to bind events to
the methods used to handle them. The delegate allows
other classes to register for event notification by
specifying a handler method. When the event occurs, the
delegate calls the bound method.
To declare an event you use the keyword Event. Once the
event has been declared, use the RaiseEvent statement
to fire the event. An event can't be declared to return a
value.
34
35
36
37
More Robust
Strict type checking
The process of changing a value from one type to another
type is called conversion.
A conversion from a value type stores a copy of the
source value in the destination of the conversion.
However, this copy is not an exact image of the source
value. The representation is changed, and even the value
being represented might change.
Narrowing conversions change the destination copy of the
source value with potential information loss. For example,
a fractional value is rounded when converted to an
integral type, and a numeric type being converted to
Boolean is reduced to either True or False. Widening
conversions preserve the value but can change its
representation. This happens if you convert from an
integral type to Decimal, or from Char to String.
The original source value is not changed as a result of a
conversion.
A conversion from a reference type copies only the pointer
to the value. The value itself is neither copied nor changed
in any way. The only thing that can change is the data
type of the variable holding the pointer.
In the example, the data type is converted from the
derived class to its base class, but the object now pointed
to by both variables is unchanged by the conversion.
Conversions can either be implicit or explicit. Implicit
conversions may be done without any special syntax.
38
39
Better Performance
Supports free threading
Visual Basic.NET allows you to write applications that can
perform multiple tasks independently. Tasks that have the
potential of holding up other tasks can execute on
separate threads, a process known as free threading or
multithreading. Free threading allows you to write
applications that are more responsive to user input
because processor-intensive tasks can run on separate
threads and the user interface will remain active while
these tasks execute. Free threading is also useful when
creating scalable applications because threads can be
added as the workload increases.
We will have a closer look at free threading later on.
Short circuit evaluation
The operands of logical And and logical Or expressions
are evaluated from left to right. If the value of the first
operand is sufficient to determine the result of the
operation, the second operand is not evaluated. This is
called short-circuit evaluation.
In the sample, evaluation terminates, when A is false. In
earlier versions the whole expression would have been
evaluated.
40
41
+=
-=
: Subtraction
*=
: Multiplication
/=
: Division
\=
: Integer division
^=
: Exponentiation
&=
: String concatenation
Late binding
In Visual Basic 6.0, you can assign an interface reference
to a variable of type Object, enabling late-bound access
to the interface's methods and properties. This behavior is
limited to in-process calls on the same thread. Visual
Basic.NET allows late binding only to public members of a
class, and not to interface members.
42
Deterministic Finalization
An object used to be destroyed automatically
In older versions of Visual Basic, objects were destroyed
as soon as the last reference to this very object was
released, and all references held to other objects were
released, too. Setting the last reference to Nothing or
simply falling out of scope immediately triggered the
destruction of the object and released all of its resources.
No longer available with Visual Basic.NET
This whole scheme is unavailable in Visual Basic.NET.
Since the memory management is done by the .NET
Framework, which makes use of a garbage collector,
freeing up resources is done when the runtime chooses to
do so, and that is basically when there is nothing else to
do or no more resources are left. (How the garbage
collector actually works is discussed in the scope of the
.NET Framework.)
By no means can the developer rely on the runtime
freeing up a resource as soon as the reference is cut. A
form that holds a database connection being terminated
does not guarantee that the database connection is
released immediately.
Some existing programs rely on deterministic finalization.
These programs will encounter run-time problems.
One possible solution
A possible solution is to add a reference counting scheme
of your own and call a cleaning method after you do not
need the object or its services any longer. While this is a
viable solution, this approach adds a lot of complexity to
your code.
43
44
45
for
Tools
We will introduce you to the most important tools that you
will use when working with Visual Basic.NET: The
compiler, Visual Studio.NET and the Upgrading Wizard.
46
47
48
Namespaces
Organizational concept
Namespaces organize objects: they prevent ambiguity
and simplify references when using large groups of
objects such as class libraries.
Names defined within the scope of a certain namespace
are referenced from outside that namespace by qualifying
their name with the name of the namespace.
Namespaces can be nested within other namespaces.
Multiple namespaces declared in a program
It is possible to declare as many namespaces within a
single piece of code as is necessary. But usually there will
be only one, because multiple namespaces should be
kept in their own group of files for maintenance reasons.
Namespaces can span multiple programs
Namespaces can be defined using several files. No
special provision has to be made when declaring the
namespace. The runtime will take care of it.
Importing namespaces
When importing a namespace with the Import directive,
names declared within that namespace can be referenced
without qualification. All import directives must appear
after any option directives but before any type
declarations.
Global namespace without a name
There is a global namespace that has no name and
whose nested namespaces and types can always be
accessed without qualification. The scope of a namespace
member declared in the global namespace is the entire
49
50
Assemblies
Result of compiling is still a .dll or .exe file
The result of compiling a source file or a whole project is a
.dll or an .exe file, but these files do not contain native
machine code. They contain code in Microsoft
Intermediate Language (MSIL). This code is compiled to
machine language at run time. The design of MSIL makes
this a very fast process.
The result of compiling is called an assembly. An
assembly can consist of a single file or multiple files. From
a consumers perspective there is no difference. An
assembly is a logical construct; any physical files that
make up an assembly with multiple files are not physically
linked by the file system. Rather, they are linked via the
assembly manifest, and the runtime manages them as a
unit.
File contains metadata
In every assembly is a collection of additional data that
describes the elements and how the elements relate. This
metadata is contained in an assembly manifest.
This manifest describes the following:
51
52
Modules
Smallest unit that can be compiled
A module is the unit that makes up a callable program. In
Visual Basic.NET a module definition is encapsulated in a
Module...End Module compound statement.
Contains one or more classes or interfaces
The scope of a module is somewhat like global scope in a
program. At this level, class definitions are given and the
program's entry point (usually the Sub Main()) is defined.
More than one module can share an assembly
More than one module can be deployed in an assembly,
which is a multifile assembly in this case. Each module is
deployed in a file of its own.
53
Free Threading
Run multiple tasks independently
As already stated, .NET does not use COMs apartment
threading model. That means that several threads can
share objectsthey do not get their own copy of the
global data set.
That implies that the programmer has to deal with
synchronization. When shared resources are modified,
they must be locked to prevent data from being corrupted
and unlocked afterwards.
This disadvantage of more complex managing is
compensated by a gain in performance and savings in
terms of system resources.
Use AddressOf operator on Sub to declare
A thread is declared on the basis of a subroutine. In this
context the AddressOf operator is used. This C++-style
operator can also be useful when calling Windows API
functions requiring a function pointer as parameter. In fact,
this construct is based on delegates, too.
Sub cannot have arguments or return value
The Sub that is called as the starting point of the thread
cannot have parameters. To parameterize the thread,
there are some possibilities in conjunction with reflection.
Synchronization needed
Since the threads run independently against the same
objects, there is some synchronization effort. The .NET
Framework provides the Monitor class for implementing
exclusive locks and established a secure mechanism for
accessing these shared objects in a controlled manner.
54
Threading Sample
The sample shows the declaration of two thread objects, a
reader and a writer thread. Suppose these two threads
share a data structure, say a list, that the writer thread
writes to and the reader thread reads from.
The threads are started with the Start method. The Join
method allows for waiting until both threads are finished
with their work.
The actual writing and reading must be synchronized so
that no writing occurs during the attempt of the other
thread to read. This is done by calling Monitor.Enter().
Between the Monitor.Enter() and Monitor.Exit() calls the
reading and writing may be done.
The monitor object provides a rich functionality concerning
synchronization between the caller and the threads and
between the threads themselves.
55
Reflection
Mechanism for obtaining run-time information
Reflection is a whole API for examining the elements of an
application from the application itself. Any element, that is,
an assembly, module, class, or thread, can be the target
of a reflection call.
In the System.Reflection namespace there are classes
for all these elements. Each of these classes provides a
set of methods to explore the whole application domain.
The App object in Visual Basic 6 was something similar.
Provides explicit late-bound method invocation
Reflection allows for an explicit late-bound method
invocation mechanism. This mechanism looks very similar
to the good old IDispatch.Invoke: actually the method is
called Invoke.
Given an object, you can reflect on the type of this object
via GetType(), examine whether this type supports a
method (via GetMethod()), and call the method Invoke
on this type with the method name as parameter.
May even construct types at run time
.NET delivers an additional API:
Reflection.Emit: It is to some extent the counterpart to
the reflection API in that it allows not for examining types,
but rather for constructing types at run time. These types
can actually be the same as with reflection: classes (with
members and methods), threads, modules, or assemblies.
56
Attributes
Additional declarative information on program item
Attributes enable you to specify information about entities
defined in a Visual Basic.NET program. Attributes can
apply to entire assemblies, modules, or smaller program
elements such as classes or properties. These attributes
are a declarative way to categorize program elements.
May define custom attribute classes
The .NET Framework predefines some attribute types and
uses them to control run-time behavior. But the developer
can define custom attributes for any entity having any
type, for example, String or Integer.
To accomplish this task, the developer has to derive a
class from the System.Attribute class or a more
specialized class. In its most simple form, an attribute can
be present or not, but attributes can have members like
regular classes, even methods.
Can be retrieved at run time through reflection
It is through reflection that the programmer can examine a
type or a program entity to determine whether a certain
attribute exists and how it is parameterized. Methods can
also be invoked via reflection.
Enhance program functionality
Attributes can be used to give hints to the system runtime
by using standard attributes. In the example, the attribute
WebMethod is a signal to the design tool that this is a
method callable in a distributed environment. The sample
shows how different members can be grouped together.
57
Windows Forms
New forms library based on .NET Framework
Because applications can now be written in a mixed
language environment, it became necessary to provide a
common library for the user interface instead of keeping
the language-specific classes. So the .NET Framework
provides such a library.
Can be used for desktop applications
The System.WinForms namespace contains classes for
creating Windows-based applications that take full
advantage of the rich user interface features available in
the Microsoft Windows operating system. In this
namespace you will find the Form class and many other
controls that can be added to forms to create user
interfaces.
Local user interface for three-tier applications
A new feature of this library is the support for three-tier
applications. Applications can be easily distributed to
client, logic, and data layers.
58
Command-Line Compiler
Compiles Visual Basic source into MSIL
As an alternative to compiling Visual Basic.NET programs
from within Visual Studio.NET, you can use the Visual
Basic.NET compiler from the command line to produce
executable (.exe) files or dynamic-link libraries (DLLs).
Can have a multitude of options
The Visual Basic.NET command-line compiler supports a
complete set of compiler options that control input files,
output files, assemblies, and debug, and preprocessor
options.
Can be called from arbitrary environment
If for some reason you want to use a different
development environment than Visual Studio.NET or want
to build systems in a batch build, the command-line
version is the tool to use.
Uses fewer system resources than Visual Studio
If your development machine has only limited resources,
the command-line version in conjunction with a small
editing environment and the several SDK tools like the
debugger or the disassembler can be the only viable
choice.
Can be used with Nmake
If your project comprises not only.NET modules but also
regular windows DLLs or resource files built with thirdparty tools, you might consider using batch processing
with Nmake.
59
Visual Studio.NET
Built around the .NET Framework SDK
The next generation of Microsoft Visual Studio is the
integrated development environment for the .NET
Framework SDK and, of course, also the evolutionary
environment for building COM-based applications.
Improved integration and functionality
Visual Studio builds on the original idea to provide the
most productive development environment. It also finally
realizes the vision of having all Microsoft languages
sharing a single and consistent development environment
with shared tools for database creation and object
modeling.
Using the .NET Framework common language runtime
you can have projects with multiple languages, choosing
the right language for each particular task.
To get you up to speed in the new world of the .NET
Framework, Visual Studio.NET includes Dynamic Help,
which anticipates questions you may want to ask as you
are writing your code, and IntelliSense code completion,
which helps you produce code more quickly.
Highest productivity for all
With a balance between support for rapid application
development and being an excellent solution for codeveloping large projects, Visual Studio.NET provides the
highest productivity for every developer.
60
61
62
63
64
Summary
Summary
The new edition of the Visual Basic development system
has significant improvements. New concepts like full
object orientation, structured exception handling,
delegates, and events may demand a steep learning
curve, but the benefits are worth the effort.
BASIC has come of age. Many remainders from the very
beginning of BASIC have been taken out of the language.
Using the new Visual Basic.NET language, your
components and their code can easily be reused even
from different languages. The new Windows Forms library
that replaces the old Visual Basic forms is one of the
necessities to accomplish this.
The Upgrade Wizard and numerous documented
procedures for migrating from Visual Basic 6 to Visual
Basic.NET help you with the step forward.
After the change, Visual Basic.NET is more of an allpurpose tool than ever before.
65
Duwamish Online
The Duwamish Online store is one of the Enterprise
Samples delivered with the Visual Studio.NET product.
Duwamish implements a fictitious e-commerce bookstore
complete with catalogue, personal profile management,
and order handling.
The Duwamish Sample is shipping in both a C# and a
Visual Basic.NET version. Before we start the walkthrough
for the technologies that have been presented in this
module, you will first learn how to install the Duwamish
sample and how the sample is organized.
66
the
Installation Tasks
Before you install the sample, you should check the
following prerequisites:
You should install the sample on Microsoft Windows 2000
Server with Microsoft SQL Server 2000 preinstalled.
Duwamish Online uses the English Query feature of
SQL Server, so you should make sure that this feature is
installed for SQL Server 2000.
For more detailed instructions you should read the
Readme.htm file before proceeding.
Once you are sure that your system has all of the required
components, run the Duwamish.msi installer package by
double-clicking it from the Microsoft Windows Explorer.
67
68
69
Common Components
Duwamish7.Common
The Common namespace (and subproject) contains all
configuration options that are common to all parts of the
system.
Also common to the entire system are the definitions for
the catalogue (Books, Categories) and the order system
(Customer, Order Data) and consequently they are also
located in this shared project that is being used by all
layers.
While the data is held in ADO.NET DataSets, this should
not be confused with being the actual database layer. The
Common namespace provides its own, internal relational
view of the Duwamish data thats being mapped to a
physical data store by the DataAccess layer (next slide).
Duwamish7.SystemFramework
The SystemFramework contains all utility classes that are
implemented to serve a specific technical purpose but are
not immediately related to the business code. All of the
code in this project is generally useful and applies to
projects beyond the scope of Duwamish.
It contains diagnostic utility classes, pre and post
condition checking, and dynamic configuration tools.
70
Duwamish7.DataAccess
Contains all database-related code
The DataAccess namespace contains all databaserelated code in Duwamish, providing a central point for
maintenance if the underlying data model needs to be
optimized or extended.
The DataAccess module maps the common definitions for
the internal data representation that are defined in the
Common.Data namespace to the physical layout of the
underlying database.
Uses ADO.NET architecture
The project builds on the ADO.NET infrastructure and
uses the SQL Server managed provider to access the
data store.
To retrieve and manipulate data, DataAccess uses
DataSetCommands bound to the DataSets provided by
the Common.Data subsystem.
Optimized for performance using stored procs
To optimize performance, the sample uses only a minimal
set of ad hoc SQL commands and relies heavily on
stored procedures, which are substantially faster.
71
Duwamish7.BusinessRules
Implements all business rules
The BusinessRules layer serves to implement all logic that
is mandated by the system requirements. It validates
data, implements calculations, and performs the
manipulation of data.
All data access performed through DataAccess
All modifications that are being made to the underlying
data store are performed through the DataAccess layer.
72
Duwamish7.BusinessFacade
Implements logical business subsystems
The BusinessFacade sits on top of the BusinessRules
and provides a logical subsystem view. The
BusinessFacade provides consistent, separate interfaces
to the customer system, the order system, and the
product system.
While data is read through the DataAccess layer, all
manipulation is validated and performed through the
BusinessRules.
73
Duwamish7.Web
Implements the user interface for Web access
The Web namespace implements the full user interface
for the application.
Uses ASP.NET architecture
The UI is built on top of ASP.NET using Web Forms,
custom Web controls, validation, code behind forms, and
many more ASP.NET innovations.
All functionality accessed through BusinessFacade
Of course, all of the data displayed to the user and all
interactions run through the BusinessFacade. This layered
model enables reusing the entire back end for a shop with
a radically different look and behavior or to expose parts
of the application as a Web Service or a Windows Forms
application.
74
75
76
77
If you scroll down a few more lines, youll see how the
method accesses the BusinessRules. It creates a new
instance of the Order class from the BusinessRules
namespace using the new keyword and subsequently
calls the CalculateTax and CalculateShipping methods
on the new object before the method returns.
Since we have seen how the business rules are being
used, were now certainly interested to see how they are
implemented.
Go to the Class View tool window and expand the
BusinessRules project node. Youll find the Duwamish7
node for the main namespace, which youre also
expanding; likewise you do it for the BusinessRules
namespace node.
If you now expand the Order class node you will find,
among
other
things,
the
CalculateTax
and
CalculateShipping methods that weve seen being called
in the business facade.
Double-click the CalculateTax node. The code that we see
here, calculating sales tax at a fixed rate of 10% for
everybody, is really not accurate for selling over the
Internet, is it? Were going to fix this a bit later.
And since you know all the navigational tools by now,
were going to skip most of the click here, click there part
from here on.
DataAccess
Open the source for the class DataAccess.Books. This
class serves to access the catalog information for the
Duwamish bookstore that is stored in a SQL Server
database.
At the top of the class, youll see that it defines a few
enumerations, which are all selectors for specific behavior
of methods.
Select the expression NaturalLanguageResponseEnum
and press CTRL+F; in the search dialog box just press
RETURN and then ESC to leave it. Now the edit cursor
should be at or around line 318.
Without really going into the details of what the code
does, you can see the enumeration is used to select a
certain execution path in a Select...Case statement. This
is certainly more readable than using numbers.
SystemFramework
Before writing some code to resolve the problem with the
tax rate that weve discovered above, were looking at one
more class: SystemFramework.ApplicationAssert.
78
79
Extending Duwamish
That should be enough looking around for now; let us
build something.
The Problem
Remember that we stumbled over a problem with the tax
calculation when we browsed through the Visual
Basic.NET code. The issue at hand is that Duwamish
flatly calculates a tax of 10% for all books sold,
independent of buyers shipping address. And for most
countries, including the United States and the members of
the European Union, out-of-country sales are not subject
to sales tax.
So, obviously this is a conceptual defect and we have to
fix this. The approach we will choose is first to implement
specialized tax calculation business rules for domestic
sales and foreign sales.
Since the decision on which rule to apply is actually yet
another business rule, we have to create that as well.
The Design
What we want to do is to reuse the Order class and its
shipping cost calculation but want to specialize just the tax
calculation part.
To do this we create two new classes, DomesticOrder and
ForeignOrder, which both inherit from the Order class and
specialize the behavior. The method CalculateTax of the
Order class becomes therefore abstract and virtual,
indicating that it can be overridden and that this actually
must be done, because the base class does not contain
any implementation.
80
81
82
Duwamish7.BusinessRules.Order.
Thats
certainly
expected, since we made the class Order abstract
ourselves. Just keep the Task List around as is.
To hook the new rules into the applications, create a new
class
OrderRule
and
add
it
to
the
Duwamish7.BusinessRules namespace (youve learned
all the required steps above).
In that new class, add a shared (class-)method with the
following signature:
Public Shared Order Create(ByVal Country As String)
Now look at the two entries that sit waiting in your Task
List. If you double-click the entries, they will take you right
two the last two places where we need to make changes.
The offending statements are of course those that create
the BusinessRules.Order class. Replace the expression
with the following lengthy expression:
OrderRule.Create( CStr(
Order.Tables(OrderData.SHIPPING_ADDRESS_TABLE).
Rows(0)(OrderData.COUNTRY_FIELD)
))
83
Legal Notices