In each of the Chapters 2, 3, and 4, our study of design patterns was focused onto one of the three tiers of a 3-tier architecture – the data layer, the business rules layer or the presentation layer. In this chapter, we acknowledge the fact that a tiered application may very well be distributed; and so we consider the value of design patterns in a distributed system – specifically, one that uses .NET Remoting.
.NET Remoting is a development framework that assists developers in creating applications that are distributed across process boundaries and machine boundaries. In this chapter we will see how design patterns can pay their part in implementing the distributed nature of a distributed application.
Moreover, we will see how .NET Remoting, as a development framework, has recognized the potential of certain design patterns in the field of distributed applications, and also aids developers in the use of design patterns. With the help of the right tools, many of the pattern details are shielded and much boilerplate code is already implemented, and hence we can avoid implementing those patterns from the ground up. Of course, the benefits of that are obvious: we save ourselves work and brain power, reduce the risk of error-prone implementations, and thus create time to focus on other more specific problems.
In this chapter, we will build a simple distributed application whose implementation is aided by use of a number of GoF patterns: Singleton, Proxy, Adapter, Observer, Decorator and Template Method. The application will also make use of a non-GoF pattern known as the Asynchronous Programming pattern. We'll illustrate how the .NET Remoting framework supports the use of these patterns in a developer's design of a distributed system as we walk through the example.
.NET Remoting – A Primer
Let's start with a quick tour of some basics of .NET Remoting. We'll briefly go through some concepts and terms in .NET Remoting in this section and set the background for later discussion. .NET Remoting is a complex subject, and an introductory treatment of the subject is beyond the scope of this book. There are a number of resources on the Web; and for a good introduction to .NET Remoting for VB.NET developers, try a title like Professional VB.NET, Second Edition (Wrox, ISBN 1-86100-716-7). Like a number of other technologies (DCOM, Java RMI, CORBA's IIOP/GIOP), the objective of .NET Remoting is to help in the development of objects (or components) that can be consumed remotely in an object-oriented way. When we say that an object is consumed remotely, we mean that it is called by another application that exists in a different process – possibly on another machine. The following diagram shows the relationship between a .NET Remoting server and client, and how they fit into the big picture:

Relationship between a .NET Remoting server and client
Remoting Objects and the Host Server
In the diagram, the first thing we see is that Remoting objects reside in a host server. (In the sample application in this chapter, the host server will be an .exe executable application.) The objects themselves are classified into three types – Client-activated, SingleCall, and Singleton. Each Remoting object falls into one of these three categories, depending on how the object is activated and how its state (the values kept by its member variables) is maintained:
- A client-activated object is, quite simply, an object that is activated at the client's request. A client-activated object can hold state information between any number of method calls triggered by the same client. However, a client-activated object does not allow you to share state information among several clients – it is associated with one client only.
- A SingleCall object is a server-activated object. A new SingleCall object is created each time one of its methods is called, and the object is destroyed when the call is completed. Consequently, a SingleCall object holds no state information between method calls.
- A Singleton object is also a server-activated object – but this type of object is one that services multiple clients. There can be only one object instance of a Singleton class. The state of a Singleton object is shared among clients. This type of object is called Singleton precisely because it follows the GoF Singleton design pattern.
A Remoting object can reside within a host application (an .exe file) of its own; alternatively, it may be hosted by IIS or by the .NET Component Service.
During the course of the sample application in this chapter, we'll build remote objects of all three types.
Channels and Protocols
Communication channels between client and server can include HTTP, SMTP, TCP, and so on. Note, however, that only TCP and HTTP channels are included as part of the .NET Remoting framework.
When using an HTTP channel, we send request and response messages using the Simple Object Access Protocol (SOAP). SOAP is the protocol at the core of web services. Like DCOM's ORPC (Object Remote Procedure Call) and IIOP/GIOP, SOAP is a protocol for consuming server objects remotely. But unlike its counterparts, SOAP messages are in XML format.
Note: If you'd like to know more, you can find the SOAP specification at http://www.w3c.org. Don Box's article SOAP Increases Interoperability Across Platforms and Languages (MSDN Magazine, March 2000) is also an invaluable read.
The Client, the Proxy, and the soapsuds.exe Utility
The figure above also shows one of a number of ways that a client can generate a proxy for a remote server object.
Also in the diagram above, we can see that the client application uses a proxy to communicate with the remote server object. The proxy represents the server object on the client side. In order to represent the remote server object, it needs to know about the server object's type information.
The diagram shows just one of several ways that a client can get information about a remote server object. The soapsuds.exe utility is provided by .NET, and can be used by the client to get the service description of a Remoting object. The service description contains the server object's type information. If the client has a local copy of the .NET Remoting server assembly, soapsuds.exe can also use it to generate a proxy. .NET Remoting is all about exposing remote objects for clients to consume.
The Configuration File, Default.cfg
.NET Remoting allows us to extract some attributes of server objects and put them into a separate configuration file, called Default.cfg. We can use Default.cfg to specify what port and protocol the server object will use to communicate with clients, whether the server object is a Singleton, SingleCall, or ClientActivated object, and sometimes what formatter should be used to serialize objects into streams.
The advantage of this design is that it allows us to change the behavior of the Remote object simply by changing the settings in the object's Default.cfg file. It means that we don't have to recompile the source code for the Remote object itself or the application that hosts it.