No. Not procrastination. Me. I stole a couple of hours off my employer today to write a bit more of my application. Don't tell, will you.
I've mentioned before how this project is building an application that has layers: the presentation layer, the business logic layer and the data layer. The interesting bit, from a programming point of view is in getting the bits to talk to each other; in particular in getting the presentation layer to talk to the business logic layer.
In the old days of plain vanilla C programming, developers would have to set up a connection between the remote objects using something like the Berkley sockets library. Not only that; they would also have to create a protocol of some sort to enable the objects at either end of the communication to talk to each other. This may sound quite easy, but in fact it's very hard.
Computer programs these days don't just deal with simple scalar types like integer numbers or ASCII characters. Because every computer program is a model of the real world, in some sense, programs have to create and manipulate complex software artefacts that contain internal data (state) and behaviours (methods). Passing objects of these types over a serial cable between distant computers involves a process called, not surprisingly, serialisation - or, as the Americans will have it, serialization.
Manually creating your own protocol for serialisation, which is sometimes also called marshalling, is not a thing to be done lightly; so programming systems have developed ways of doing all this in the background so that the developer doesn't have to worry about it. This is something that, in my opinion, .NET is particularly good at.
But it's very detailed and exacting work. Over time, I've developed a way of working that helps me through the complexity. First I create the object that is going to be called remotely. In .NET this means creating an object that inherits from a class called MarshalByRefObject. I give this object all the state and methods (data and behaviour) that my model - the UML, remember - called for. I then build another object, called a local client, that will call the remote object locally for testing purposes. When I'm sure that this works as it should, I create what is known as a proxy object. This is what will be called on the remote client side. It interacts with the remoting infrastructure provided by the .NET Framework to provide marshalling and unmarshalling facilities that allow you to pass complex structures over the wire. Think of it like encryption and decryption, if you like.
When I have all that ready, I build a server that will listen on a port on the server for requests from the proxy. When it gets a request, it passes it on to the remote object, and the remote object carries out the requested task and returns whatever kind of object the client expects.
Then a remote client has to be built. It would be possible to use the client-side code in the application's presentation layer for this, but it's easier to build a little Windows Forms program (a GUI, if you like) that calls the remote object remotely and tests all its functions. Actually, it calls the proxy: but it thinks it's calling the remote object although it's the remoting infrastructure that does that in reality.
This is where I got to today. The journey was not without difficulties, but I can now call my remote object remotely and get back the answers I expect - data from the remote database, in this case. There's still quite a lot to do, though. The next step is to replace the console-based server I wrote today with a proper service that will run in the background even when no-one is logged on to the computer. Most people who have only dealt with personal computers find this a bit hard to understand, but there's not a lot to it, really. You just have to understand that it isn't necessary for anyone to log in to the machine for it to be fully functional. It just isn't accepting instructions from a human being - or at least not one who is logged in locally.
The final step will be to hook up the presentation logic in the code-behind pages of my ASP.NET application to the remote object, in response to the appropriate events. For example, the drop-down list box for countries needs to be populated with a list of countries from the database in response to the page load event of the demographic details page.
Hopefully I'll complete these steps on Saturday; unless I can steal some more time, of course.




10/02/06 @ 22:27