Thursday, February 11, 2010

Wrapping WCF Services in a Using Statement

Considering that the WCF Services I've created for my budget application are the first I've written, I hadn't actually given much thought into how I would actually call them.

Here's what I came up with!

IMthService svc = new MthServiceClient();
svc.Save( newMonthObject );

Of course, what I discovered was that my services were timing out after the sixth call (not sure why it was six as the default is ten). Any how, I quickly discovered that while the service that's is written doesn't directly inherit from IDisposable, the service client does. So in effect my code was not disposing of the service client properly. So how do I dispose of the client considering that the Dispose method is private? Easy, call Close or Abort. Duh!

There are various posts floating around that instruct on wrapping your service call in a try catch, but I didn't want to write try{...}catch{...} time and time again.

It was at this time that I recalled reading a nice post about a common WCF exception message that provided a nice little solution to my problem. Thanks Damien McGivern for coming up with the following solution.

public static void Using<TService>( Action<TService> action )
  where TService : ICommunicationObject, IDisposable, new()
{
  var service = new TService();
  bool success = false;
  try
  {
    action( service );
    if ( service.State != CommunicationState.Faulted )
    {
      service.Close();
      success = true;
    }
  }
  finally
  {
    if ( !success )
    {
      service.Abort();
    }
  }
}

So now I can call my services like this...
WCFHelper.Using<MthCategoryServiceClient>
  ( svc => svc.Save( mc ) );
and
WCFHelper.Using<MthCategoryServiceClient>
  ( svc => mthCategories = svc.GetByMonth( mthId ) );

Enjoy

No comments:

Post a Comment