Call Behaviors

What are Call Behaviors? Well if the term isn't self explanatory to you I will quickly explain what it does. Remember currently when you do WCF calls you generally need to do something like this (OK, I know you guys don't do this because people have found ways to simplify it but Microsoft recommended this in the beginning as the safe way):

MyProxy proxy = new MyProxy();
try
{
    proxy.DoMyMethodCall();
    proxy.Close();
}
catch
{
    proxy.Abort();
}

This is a bit much for one call, let alone the hundreds of other calls you need to make in your application or system.
That is essentially call behavior. When you perform a call, it needs to obtain a channel, make the call, perform a close or abort if something went wrong.
Well, this is how the Default call behavior works in EasyProxy which is called DefaultCallBehavior .

If you have a different Call Behavior that you would like to use, you can substitute that on your CreateProxy call. Please see Simpler configuration of proxies on how to do that.

So if you would like to create a custom one, you are more than able to do that. Let's say you would like to retry the call 2 more times if they fail consecutively, you could do something like this:

First you need to create a class that inherits from CallBehaviorBase<TContract> .
You will notice that the base class constructor requires a ChannelAllocatorBase<TContract> instance to be passed to so please add that to your constructor.

Then you override the InvokeOperation() method.
public override object InvokeOperation(MethodInfo targetMethod, object[] arguments)
{
    int retries = 3;
    Exception lastException = null;
    while(retries > 0)
    {
         // Get a channel first before we begin
         ChannelHolderBase<TContract> channelHolder = _channelAllocator.GetAvailableChannel();
         try
         {
             // We make the call
             object result = targetMethod.Invoke(channelHolder.Channel, arguments);
             // If it was successful we send to the channel holder that we're done with this
             // channel and that it can dispose of it if it wants to.
             channelHolder.EndCall();
             // We end the invocation with a result (if there is any, remember this is reflection).
             return result;
         }
         catch(Exception ex)
         {
             // If something went wrong, we need to retry
             retries--;
             // We catch the last exception
             lastException = ex;
             // We need to tell the channel Holder that the channel is no longer valid
             channelHolder.AbortCall();
         }
    }

    if(lastException != null)
    {
        // We need to signal to the one that called this proxy that something went wrong
        throw lastException;
    }

    // We shouldn't get to this point but for the sake of the compiler:
    return null;
}

This is by no means a very "production ready" implementation but I think it should explain to you very nicely what can be done with Call Behaviors.
So now when you do something like this:

proxy.CallMyServiceMethod();

It will actually try 3 times if the first 2 times fail for some reason or throw an exception if on the 3rd time it still didn't succeed.

Last edited Jun 2, 2013 at 9:42 AM by dandrejvv, version 4

Comments

No comments yet.