Return Callbacks and the Disconnected Service Agent

Standard

 

In my previous post,  I a sample “Service Agent” in VB.  I will now extend the example to provide notification of results.

The form “MainForm” has now been extended to listen to a new shared event “AddReturn” on the service agent.

Public Class MainForm

Private WithEvents moManager As RequestManager = DatabaseRequestManagerIntializer.Initialize("QueueDatabase")

Private moMyCalculator As New CalculatorServiceAgent(moManager.Instance.RequestQueue)

Private Sub cmdDispatchMessages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDispatchMessages.Click
    moManager.DispatchAllPendingRequests()

End Sub
Private Sub cmdSubmitLocalRequest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSubmitLocalRequest.Click
    moMyCalculator.Add(1, 1)
End Sub

Private Sub Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    AddHandler CalculatorServiceAgent.AddReturn, AddressOf OnAddReturn

End Sub

Private Sub OnAddReturn(ByVal a As Integer, ByVal b As Integer, ByVal ans As Integer)

    ' WARNING:  Me.Invoke should be used to do UI operations as this event may not be executed on a UI thread.

    MsgBox(String.Format("{0} + {1} = {2}", a, b, ans))

End Sub

End Class

The Service Agent class now “wires up” the IntegerCalculatorServiceCallback class as the “ReturnCallback”.  This calls a shared method on the service agent to communicate back to the caller. 

Public Class CalculatorServiceAgent

    Private moRequestQueue As IRequestQueue

    Public Shared Event AddReturn(ByVal a As Integer, ByVal b As Integer, ByVal ans As Integer)

    Public Sub New(ByVal requestQueue As IRequestQueue)
        moRequestQueue = requestQueue
    End Sub
    ''' <summary>
    ''' Enqueues a request to the <c>Add</c> web service method through the agent.
    ''' </summary>
    ''' <returns>The unique identifier associated with the request that was enqueued.</returns>
    Public Function Add(ByVal a As Int32, ByVal b As Int32) As Guid

        Dim behavior As New OfflineBehavior()
        behavior.ProxyFactoryType = GetType(ObjectProxyFactory)
        behavior.MaxRetries = 1
        behavior.Stamps = 1
        behavior.Expiration = DateTime.Now + New TimeSpan(0, 0, 30)
        behavior.ReturnCallback = New CommandCallback(GetType(IntegerCalculatorServiceCallback), "OnAddReturn") ' If it works, make a call back here

        Dim request As New Request()
        request.MethodName = "Add"
        request.Behavior = behavior
        request.CallParameters = New Object() {a, b}

        request.OnlineProxyType = GetType(IntegerCalculatorServiceOnlineProxy)
        request.Endpoint = ""  ' Setting this to blank is important.  If sent to nothing it wont work

        moRequestQueue.Enqueue(request)

    End Function

    Friend Shared Sub OnAddReturn(ByVal request As Request, ByVal parameters As Object(), ByVal returnValue As Integer)
        RaiseEvent AddReturn(parameters(0), parameters(1), returnValue)
    End Sub

End Class
''' <summary>
''' This class is used as a mechanism to inform the caller when a request has been completed
''' </summary>
Public Class IntegerCalculatorServiceCallback
    Public Sub OnAddReturn(ByVal request As Request, ByVal parameters As Object(), ByVal returnValue As Integer)
        CalculatorServiceAgent.OnAddReturn(request, parameters, returnValue)
    End Sub
End Class

The “business logic” is unchanged.

''' <summary>
''' The proxy class is used to invoke the "real" business logic that does the work
''' </summary>
Public Class IntegerCalculatorServiceOnlineProxy
    Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer

        ' This could be a call out to a 3rd party component
        Return a + b

    End Function
End Class

The use of a shared event on the ServiceAgent itself is unique to my example.  (for clarity) The Patterns and Practices example handles this differently. 

To create events for exceptions, populate the “ExceptionCallback” property on the request object.

Going Further

I’m now considering creating a ServiceAgentBase that will make the callback events generic.   I’ll let you know how it goes. 

Links

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s