All good programmers aspire for as much code reuse as possible simply because it allows you to make
very robust and scalable applications quite easily.
There are two types of code reuse
1. White Box : This
refers to pasting existing pieces of code into a monolithic executable.
2.Black Box : This involves linking together of segments of compiled
machine code.
Hence, compiled black box class libraries from which the client application can
create objects are called
Components.
. NET, too provides the developers with ways and means to create and deploy components. Since this approach closely resembles COM, it would not be difficult for developers to get confused between the two distinctly separate approaches to component based development, so, let's take a look at these different approaches in order to eliminate the confusion.
The Birth of COM
In the early
days of programming, programmers kept their function libraries in separate files
called Object files,
which
contained the compiled version of the code. If and when the programmer needed to
use a particular object file, he compiled the client application to machine code
and then relied on dynamic linking to join the client application to the object
file to make a single executable. The only advantage being the time saved to
compile the function libraries. There were disadvantages like wastage of storage
space because each executable had a copy of the function library embedded in it.
Maintenance of these applications was difficult. If a bug was discovered in the
function library, the entire executable was to be recompiled and redistributed.
There was one more serious limitation i.e. client applications written
in the same programming languages as the function libraries could be used
together. For example, a client written in QuickBasic could not reference a
library written in C++.
Hence Microsoft came out with
COM,
which was
nothing but a specification. Components built in any language according to this
specification can be used with a client in any other language. Again the
programmer did not have worry about creating a single executable since the
component was identified by means of
GUID (Global Unique Identifier), a 128-bit number, which was
stored in the system registry along with other relevant information to uniquely
identify the component. Client applications dynamically created an instance of
the component at runtime to use the business logic in the component; hence only
one copy of the function library was required. The disadvantage was that the
developers had to contend with, what was commonly referred to as "DLL HELL". The
problem arose when a particular DLL was to be replaced by a newer version. The
developer had to remove all references to the component by shutting down all the
client applications and if that didn't work, close down the WWW service.
Sometimes even that didn't work, and the server was to be restarted before he
could actually replace the DLL.
COM+
In order for enterprise applications to be able to use COM, it had to have certain capabilities like:
- Authentication
- Object Pooling
- Transaction Management
-
Support Distributed Architecture.
Microsoft came out
with DCOM(Distributed COM)
and MTS(Microsoft Transaction Server)
so that the developers didn't have to add these capabilities to
their components. Using the above two technologies , they can concentrate on
writing the business logic instead of the background plumbing for their
components.
DCOM is an
RPC(Remote Procedure Call)
protocol used for communication between distributed components. Here the client
made requests to a "proxy" class
on the local machine which then delegated the call invisibly to a remote
"stub" class installed on a
remote machine and the results followed the reverse path from the stub class to
the proxy class to the client. Hence the client was completely ignorant of the
location of the component, which achieved
Location Transparency. The
disadvantage of DCOM was that it was a protocol which used a different hardware
port other than the default HTTP port 80, hence a different port was to be kept
open at all times in order for the components to communicate which was a major
security hazard. Hence DCOM could not work easily across firewalls.
In order to use MTS,
programmers placed special MTS hooks in their components, compiled them and
placed them in MTS packages. Keeping related components in a single package had
it's own advantages. Whenever the client requested an instance of a component in
a package, MTS ensured that a new dedicated process was created for that
package, a new instance of the component was created in that process and applied
transactional services, object pooling services and security was applied
according to the requests of the component developer.
MTS allowed related units of works to be treated as transactions which
meant that if all units of the work completed successfully, then the entire
transaction was treated as successfully completed, whereas if any one of the
units failed, then the entire transaction was rolled back.
MTS conserved memory resources by retaining the objects in memory even
after the clients who originally requested them released them , so when another
client requested for the same component , MTS would hand the retained object to
the new client. In this way, MTS eliminated the overhead on the server resources
needed to instantiate a new object.
MTS allowed developers to equip their components with security measures
for authenticating the client which requested it's services. Hence it ensured
that no unauthorized client could take undue advantage of the component.
MTS was integrated with Microsoft's Windows 2000 OS under the new name
COM+. But COM+ isn't
just MTS, it also includes a host of other services.
MSMQ (Microsoft Message Queue Server),
which was released around the same time as MTS, was also integrated with Windows
2000 under COM+. MSMQ allows for asynchronous communication between clients and
servers, which absorbed the impact of server inaccessibility.
Event Service was added so that server classes could
asynchronously communicate event occurrences to multiple clients. The
Load Balancing Service
automatically instantiated requested objects on the machine which had the most
available resources in the server farm.
. NET
. NET provides a completely new approach to creating and deploying components. They are also known as Assemblies. With COM, the developer had to register the component on the server, i.e. it's information had to be updated in the system registry. The purpose was to keep the information of the components in a central location so that COM+ can find the appropriate component. With .NET assemblies, the assembly file encapsulates all the metadata required in special sections called Manifests. In .NET, for an assembly to be available to the client, it only has to be in the same directory as the client application. When the client application requests for an instance of a particular component, the .NET runtime searches the same directory for the assembly and then interrogates the assembly's manifest to know the various classes that the component provides. Since the information about the component is kept in manifests, the developer doesn't have to register the component on the server and several versions of the same component can safely co-exist together on the same machine.
Creating a .NET
assembly is a lot like creating a VB6 component, the developer only has to worry
about the business logic, all the background plumbing code is generated by the
.NET, also since the .NET runtime maintains garbage collection externally, the
component does not have to worry about keeping it's reference count as was done
in COM with the help of the IUnknown Interface. In short, creating a .NET
assembly is easier than creating a VB6 COM.
Pure .NET assemblies can't be registered under COM+ services since
they comply with a different standard than the original COM's binary one. In the
face of .NET, there have been references to COM as "Classic COM" which could
mean that .NET assemblies are the way forward. But the dependability of current
applications on COM+ suggests that COM could be around for quite a while. That
could be one of the reasons why Microsoft provides developers with tools to use
.NET assemblies and COM together.
The
Type Library Importer (TLBIMP.exe)
utility creates .NET wrappers for the COM components so the old legacy code can
be used with .NET applications.
The Type Library Exporter
(TLBEXP.exe) utility creates COM wrappers for .NET components which could be
useful if you want to migrate your current application to .NET taking the
piecemeal approach i.e. gradually replacing the COM components with their
equivalent .NET assemblies. The services provided by COM+ can't be ignored in an
enterprise application, hence that could be one more reason why developers might
be end up making COM wrappers for .NET assemblies. Alternatively, developers can
access much of the functionality from the classes in the .NET base class
library.