Around the year my youngest son was born—about 1996—I was working on a big project in Chicago. The problem was to manage information related to tracking labor in North America, which included Canada and Mexico. If you recall, around that time we had whopping speeds of 9,600 baud on dial-up connections. Our applications had to process huge amounts of data through tiny connections over wide areas.
The application was to be implemented in Delphi, C, and DB2. At that time C was used for stored procedures, IBM's Universal database was still called DB2, and there were no ODBC drivers for DB2. We had to write everything: stored procedures in C, client software for Windows, server software, and connections to DB2 servers using a Software Development Kit (SDK) from IBM. In essence we had to figure out how to write a rough supplement for an absent connectivity layer to solve the business problem, and we had to write a distributed application for Windows.
My smart friend Andrew Wozniewicz came up with a nice solution that people had difficulty understanding but that worked in practice. The solution was to define abstract classes (remember that this was pretty early in COM's history, and I don't recall that DCOM was a choice) and then share those abstract classes on client and server. Implementations would exist only on the server. The client would declare variables using the abstract classes, and a factory method would return an actual object to the abstract variable definition. Hence, we implemented thin clients containing only abstract classes and fatter servers containing implementations for those classes. From the server to the database server we used what Andrew referred to as “amorphous blobs of data.” These amorphous blobs represented data that we created in a predetermined format to which the server application and server applications on the database server had agreed. This is pretty good multitier architecture considering the state of technology at the time. I am familiar with all of this because I implemented the proof-of-concept vertical slice from Andrew's description.
When we were finished we had a client with abstract classes, a middle-tier business layer with abstract classes, and completely implemented child classes in the middle tier, which sent amorphous blobs of binary data to the database server. On the database server the blobs were unpacked and the DB2 SDK was used to invoke stored procedures.
To Andrew's credit he figured some of this out by gleaning how Delphi's very advanced IDE—at the time—worked with the Visual Control Library (VCL) at design time to get controls from the designer onto a form. As I mentioned in Chapter 3, Anders Hejlsberg was instrumental to implementing Borland's Delphi and Microsoft's .NET. History provides perspective, and it is very likely that some ideas in .NET evolved from Anders' dozen or so years at Borland.
The problem Andrew and I and many others had still exists. How do we get applications to share data on a LAN or WAN? Worse, the problem is exacerbated now because the network includes the highly distributed, heterogeneous Internet. In addition to having to send data between client and server on a LAN and WAN, now programmers are expected to send data between multiple clients and multiple servers, potentially running different operating systems and different language-based implementations, across every kind of network. .NET Remoting is a solution to the problem of implementing highly distributed applications.
Sadly, Andrew's amorphous blobs aren't completely sufficient as a public standard. What Microsoft has done is to allow us to define interfaces or abstract classes on the client and implement classes on the server, and instead of amorphous blobs we get XML and SOAP. As open standards, XML and SOAP can be deciphered by any platform. In addition, Microsoft's .NET Remoting technology takes care of packaging the XML and SOAP blob back and forth—called marshaling—for us. For the most part we only have to worry about writing the business solution; .NET takes care of the infrastructure.
Of course, as is true with any subject, if you dig deep enough you can start customizing and extending the provided behavior. However, the ultimate end result is that .NET Remoting was defined to support a highly distributed world of TCP and HTTP networks by building on open standards and hiding the most difficult aspects of managing connections, marshaling data, and reading and writing XML and SOAP. As a result, if you can understand inheritance, declare and implement an interface, and use attributes, you are ready to begin using .NET Remoting.