.NET Remoting and Event Handling in VB .NET, Part 2

It is a bit more advanced than a basic sample because it uses some patterns (Command, Factory, Singleton, and Observer) that you might use in a real application, as opposed to just the bare minimum code you would need to connect to the remote server.

The Client class' Sub New configures the client application, creates an instance of the remote server, and connects the Client.OnMessageEvent to the remote server object, Chatter. The code never creates an instance of the Client object directly. (Note that the constructor Sub New is private.) Instead, it uses the Singleton pattern and the Client object indirectly through the read only property, Instance. Finally, the Send and OnMessageEvent event handlers handle the connection to and from the server (as discussed in the previous section.)

Implement the Presentation Code

The objective here doesn't involve Windows Forms or Web Forms; it is about .NET remoting and server events. Consequently, you can use any kind of GUI to test your solution, and that's what the example does—with a twist.

By separating your pieces and using good patterns, you can loosen the relationship between presentation, middleware, and server. You will see this in the implementation of the Console application.

Listing 5: The Presentation Layer Is a Console Application, but Good OOP Means It Could Have Been Anything

Imports SharedCode
Imports Softconcepts.ApplicationBlocks.RadioPattern
Class ClientApp
Implements IListener
Public Shared Sub Main()
With New ClientApp
.Run()
End With
End Sub
Public Sub Run()
Broadcaster.Add(Me)
ProcessCommand("Startup")
While (True)
Console.Write("chat>")
If (ProcessCommand(Console.ReadLine()) = False) _
Then Exit While
End While
ProcessCommand("Shutdown")
Broadcaster.Remove(Me)
End Sub
Public Shared Function ProcessCommand(ByVal input As String) _
As Boolean
Return CommandFactory.Create(input).Execute(input)
End Function
Public Overloads Sub Listen(ByVal message As String) _
Implements IListener.Listen
Console.WriteLine(message)
End Sub
Public ReadOnly Property Listening() As Boolean _
Implements IListener.Listening
Get
Return True
End Get
End Property
Public Overloads Sub Listen(ByVal message As String, _
ByVal formatter As Softconcepts.ApplicationBlocks.RadioPattern.IFormatter) _
Implements Softconcepts.ApplicationBlocks.RadioPattern.IListener.Listen
If (message.Equals("chat>")) Then
Console.Write(message)
Else
Console.WriteLine(formatter.ApplyFormatting(message))
End If
End Sub
End Class

The Sub Main is the entry point for the presentation layer. It is simply an instance of the contain class and a call to a single method, Run. This is pretty good encapsulation.

Except for the Imports statement, the listing makes no reference to the middle layer—Client class—or any of the remoting plumbing. This means you could strip off this presentation layer and easily put a WinForms GUI or something else on top of it.

The basic behavior is that the run method loops while there are commands to process, period. Key concepts that make this possible are grounded in patterns. Part 3 will explore all of the patterns used for this solution.

What Have You Learned?

Part 2 demonstrated how to implement the client's App.config file, so that the client could talk to the server. It also discussed why clients that handle server events have to be remotable. Because the .NET plumbing handles this for you, you really only needed to make your remotable client object inherit from MarhsalByRefObject and share that code between client and server.

All of the extra code really demonstrates the use of some very powerful design patterns. While you wait for Part 3 of this three-part installment, see if you can spot the Command, Factory, Singleton, and Observer patterns used.

Part 3 will describe and explain the implementation of the patterns, introduce internationalization in the context of this sample, and point out where code that is too OOPY can cause goofy behavior. (For fun, write me if you find the goofy behavior.)

About the Author

Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his book Visual Basic .NET Power Coding from Addison-Wesley and his upcoming book UML DeMystified from McGraw-Hill/Osborne (Spring 2005). Paul is also the founder and chief architect for Software Conceptions, Inc, founded 1990. He is available to help design and build software worldwide. You may contact him for consulting opportunities or technology questions at pkimmel@softconcepts.com.

If you are interested in joining or sponsoring a .NET Users Group, check out www.glugnet.org.