I'd like to
know if this is current practice or is there something better to use, and
where can I find examples.
An excellent question, Mark. The answer to it depends a lot on how far you
want to go with ASP.Net and with programming in general. For example, if you
anticipate further expansion of your applications, learning more about good
OOP design and architecture would be a great idea.
First, let me recommend a great Microsoft resource, which is their "Patterns
and Practices" web site:
http://msdn.microsoft.com/practices/
This web site is a wealth of both information and useful code resources. I
think you will enjoy reading the various articles there, and may find that
some of the free libraries they offer will save you a lot of time.
From the code you've posted, I can see that you're doing well with the
syntax differences between ASP.Net and ASP, and seem to be getting familiar
with the ADO.Net family of data classes. It also seems to me however, that
your mindset remains procedural, rather than object-oriented. This is the
most important difference in the .Net platform.
Object-oriented programming came about in the natural evolution of
programming, as a result of, as with all other evolutionary steps in the
chain, the increasing complexity of applications and the systems on which
they run. A bit of history might be helpful here.
In the beginning, man created the 1 and the 0 (a little Biblical humor
there). Computers are called "computers" because they always have been
essentially, calculators. A processor does nothing but perform mathematical
operations. And the mathematical language of computers is binary (base 2),
with the numbers 1 and 0 representing "on" and "off" states in electrical
circuits. So, the first computers were programmed by feeding in a stream of
1s and 0s to the processor, and translating the binary output to something
meaningful to humans. While there were several different methods of doing
this, you are probably most familiar with the punch card. A punch card is a
card which has holes representing 0s. Where there is no hole, the number 1
is implied. To write a program, a programmer would take a stack of these
cards and punch holes in them to represent the numerical input to the
computer. The sequence of the 1s and 0s represented either commands or data.
Of course, it wasn't long before computers began to increase in capacity and
power, particularly with the advent of the microchip. So, the process of
writing binary code as computer instructions began to become
cost-ineffective. At the same time, it was observed that typically, these
instructions were combined and repeated in patterns to perform various
tasks. So, an intermediate, character-based, human-friendly programming
"language" was born: Assembler. This also precipitated the first compiler,
which would read Assembler code, and turn it into machine language (1s and
0s).
Again, computers continued to grow in capacity, speed, and power, and the
demand for even more powerful and complex programs resulted in the
development of the so-called "high-level" programming languages, such as C,
Fortran, Pascal, COBOL, and BASIC. These languages worked on the same
prinicple as Assembler. Assembler commands were often used in repeating
patterns to perform similar tasks. The idea of the higher-level languages
was to create languages which could contain functions that combined various
combinations of Assembler instructions without having to re-write those
Assembler instructions over and over, thus saving time. These languages were
also extensible, in that, various functions could be re-combined with other
functions to create new functions. Now the compilation process was a 2-step
process: The high-level code was compiled to Assembler, which was then
compiled to machine language (1s and 0s).
And yet, computers continued to evolve. A processor can perform exactly one
mathematical operation at a time. But some people got the very clever idea
of using a looping structure to "time share" the processor between various
tasks which could appear to run at the same time (by virtue of the sheer
speed at which the processor operates, like a movie). Multitasking computers
were born, and the multitasking "loop" structure was hidden inside the
Operating System. but programs could also be multi-task programs, each using
a set of its own (hidden) loops to share its share of the processor between
various tasks. Now, the world of programming took on a level of complexity
that could boggle anyone's mind. Loops within loops within loops... what a
tangled web we wove!
This was the origin of object-orientation. One of the principle aspects of
OOP is to hide complexity that is not necessary to be known to the
developer. This is done by means of a couple of the pillars of OOP:
Abstraction, and Encapsulation.
Abstraction is a term for a way of thinking about things in a very human
way. A program is nothing but process and data. But so is everything else in
the universe. To "open a Connection to a database" is actually a process
which involves putting together data in a useful way that can be used to
communicate between one application (process) and a database application
(another process). So, rather than thinking about all of the complex work
involved in the process, it is encapsulated into an object, called a
Connection.
The difference between a class or object and a function is that a function
has data that is stored within the function for the lifetime of its use
(while it is running), and is in essence simply a process, or a sequence of
instructions. A class or object can contain both process and data, and can
expose its data to other objects. In addition, it does not "run," but simply
"exists." It has functiions or processes which *can* run when called upon to
do so. But it must be explicitly created, and explicitly destroyed, whereas
a function's lifetime is from the time it is called to the time it finishes
running its process. It is a subtle but significant difference.
Encapsulation is the ability of a class or object to share or hide data, in
essence hiding complexity which is only useful to itself, and exposing a
relatively simple "interface" of data (fields and properties) and process
(methods, another name for functions, but within the context of an object).
A car has a complext engine which performs the actual work, but this is
hidden under the hood. The driver sees only the steering wheel, gear
shifting controls, brake, gas pedal, etc., making it easy to use a car
without knowing how it works.
The difference between a class and an object is that a class is a pattern or
design for objects. An object is an "instance" (working copy) of a class.
There's a good bit more to it than that, but I'm hoping to give you enough
to get you interested and started, and let you take it from there.
The beauty part is that one can design one's own classes, just as one can
design car or truck engines by combining various engine parts together in
different configurations. Once you develop a good set of configurable (or
"extensible") classes, you can re-use them in various applications which
perform similar work, without having to write them all over again.
Getting back to the code you posted, you may have noticed that similar code
appears throughout your application. The process of opening a Connection and
fetching data, when using the same database or data source, is almost
identical. The classes of the .Net CLR are designed like engine parts, to be
useful in a large variety of configurations, to connect to any kind of data
source. But *you* Mark, are only connecting to one. So, you can create your
own "Database tier" of custom classes which perform all of these sequences
in the same way without having to rewrite all that code over and over again.
If you want to expand your enterprise, you can get even more
compartmentalized, by creating a business tier, which performs operations
"under the hood" without having any user interface, and a "presentation"
(user interface) tier, which exposes the business objects in a user-friendly
way. This way, you can create, for example, another interface for the same
type of applications, exposed as a Windows Form executable, or perhaps a Web
Service.
At any rate, the link I posted should give you a lot of useful information,
and a lot to think about, as well as some really nice, pre-built libraries
for implementing various common "patterns" of applications.
--
HTH,
Kevin Spencer
Microsoft MVP
Professional Numbskull
Show me your certification without works,
and I'll show my certification
*by* my works.