Creating the client through the factory interface will truly tickle the OO geek in you. When you call the
CreateAccountTestInstance() method on the "function library like" instance of the factory object, it returns full fledged instances of objects that execute completely on the server.
Object o = Activator.GetObject(
typeof(IAccountantExamFactory),
"tcp://localhost:9988/IExamFactory");
IAccountantExamFactory factory =
(IAccountantExamFactory)o;
Voila, you can now create a CorporateAccountantExamFactory using only the IAccountantExamFactory interface! The server implementation can create new versions of both the factory and the implemented objects without having to change any client side code whatsoever.
IAccountantTest iat = factory.CreateAccountTestInstance()
IAccountantTest is the interface for CorporateAccountantTest. If at a later date you need to create a different implementation of the IAccountantTest interface, all you would have to do is have the CorporateAccountantExamFactory return the new type.
Listing 4 contains a complete listing of this client.
Passing Objects By Value
Sometimes you want to work with a complete local copy of an object rather than a server-based reference like those you can create using the factory pattern. One reason you might want to do this is to reduce network traffic. For example, if you create an object that models a person's address and make three separate calls to
GetCity(),
GetState() and
GetZip() the code would make three separate round trips to the server over the network, which is very inefficient.
To have your object passed by value you must add the Serializable attribute to the class rather than inheriting serialization capability from MarshalByRefObject. However, you should be aware that doing so causes some changes in the way you distribute the application. You can only pass an object by value if it is a
well-known object type. This means that the client has to have a copy of the DLL containing the implemented version of the object, not just the interface. That's because the serialized version of the object doesn't include any of the object's method codeit contains only the object's data.
Putting It All Together
You can download the complete source for this solution from the References column of this article. To run the code, open the solution file "DevXRemotingClients.sln" in Visual Studio.NET and compile and run it. The solution contains four projects.
- The Interfaces DLLRemotingClient.exe
- The Implementation DLLRemotingClientsInterfaces.dll
- The Server ObjectRemotingServer.exe
- The Client ObjectRemotingExampleImplementation.dll
I urge you to experiment with the projects. Modify the interface so it includes a get/set address. Create a serialized Address object to get a feel for how it works. Keep modifying it until it breaksand then fix it!
.NET Remoting gives you a powerful tool for using remote objects across the network. Using the factory method described in this article, Remoting provides a simple and effective way to use full fledged remote objects instead of function libraries with complete separation between the interface of the client and the actual implementation on the server.