Saturday, December 09, 2006 8:22 PM Erwyn van der Meer

WCF Service Proxy Helper

When you create a Windows Communication Foundation (WCF) service proxy class for a service by using svcutil.exe, it creates a proxy that derives from System.ServiceModel.ClientBase<TChannel>. This class implements IDisposable so you think you can use your proxy safely in a C# using statement and get guaranteed clean-up in the face of exceptions.

However, the System.ServiceModel.ClientBase<TChannel> class can throw exceptions from its Dispose method, because it calls its Close method. This can happen when it is in a faulted state. In that case you have to call Abort for clean-up. Most times you are not interested in knowing whether the Dispose fails or not and you just want to have guaranteed clean up of any resources held by the proxy.

Check out this discussion on the WCF forum for why Microsoft implemented the dispose in this way.

To prevent you from writing a lot of code to accomplish this clean-up, I have written a generic ServiceProxyHelper class that does it for you. You can download it here or view the code below. It only swallows expected exceptions in its Dispose method but it always cleans up by calling Abort.

The idea is that you derive a class from my ServiceProxyHelper<TProxy, TChannel> class. Insert your proxy class (that should derive from ClientBase<TChannel>) name for TProxy, and the service interface name for TChannel. The helper class wraps the proxy and doesn't directly expose its methods. From your derived class you can use the protected Proxy property to get access to the service proxy. You should add methods to your derived class that delegate to the proxy.

For our project we added convenience method to the derived helper that create request messages and unpack response messages. So our helper methods have a different signature than the methods on the proxy class itself.

This code is provided "AS-IS" without any warranties. You can change it to fit your needs.

 
using System;
using System.Collections.Generic;
using System.ServiceModel;

namespace LogicaCMG.ServiceAccess
{
    /// <summary>
    /// Generic helper class for a WCF service proxy.
    /// </summary>
    /// <typeparam name="TProxy">The type of WCF service proxy to wrap.</typeparam>
    /// <typeparam name="TChannel">The type of WCF service interface to wrap.</typeparam>
    public class ServiceProxyHelper<TProxy, TChannel>: IDisposable
        where TProxy : ClientBase<TChannel>, new()
        where TChannel : class
    {
        /// <summary>
        /// Private instance of the WCF service proxy.
        /// </summary>
        private TProxy _proxy;

        /// <summary>
        /// Gets the WCF service proxy wrapped by this instance.
        /// </summary>
        protected TProxy Proxy
        {
            get
            {
                if (_proxy != null)
                {
                        return _proxy;
                }
                else
                {
                        throw new ObjectDisposedException("ServiceProxyHelper");
                }
            }
        }

        /// <summary>
        /// Constructs an instance.
        /// </summary>
        protected ServiceProxyHelper()
        {
            _proxy = new TProxy();
        }

        /// <summary>
        /// Disposes of this instance.
        /// </summary>
        public void Dispose()
        {
            try
            {
                if (_proxy != null)
                {
                    if (_proxy.State != CommunicationState.Faulted)
                    {
                        _proxy.Close();
                    }
                    else
                    {
                        _proxy.Abort();
                    }
                }
            }
            catch (CommunicationException)
            {
                _proxy.Abort();
            }
            catch (TimeoutException)
            {
                _proxy.Abort();
            }
            catch (Exception)
            {
                _proxy.Abort();
                throw;
            }
            finally
            {
                _proxy = null;
            }
        }
    }
}
Filed under: , , ,

# Open Source Mindset in MS/.NET Land

Monday, December 11, 2006 1:56 PM by Erwyn van der Meer

Frans Bouma posted his thoughts on the reasons for the relative absence of big open-source project in

# re: WCF Service Proxy Helper

Tuesday, January 02, 2007 5:01 AM by Dennis van der Stelt

I'm not getting why you wrote this. According to Reflector, when Dispose is called, Close() is called, which calls Close with a timeout. This would mean you'll always go to label Label_00BA:

From there on, there's a try & finally which will in all cases call the abort method. And that's exactly what the problem is, because you don't always want to call abort. Abort means you pull out your UTP cable and the service and client can't chat anymore about ack messages and transactional stuff.

According to the thread you're referring to, IDisposable was left in because users think using "using" is usefull. (Still got that? ;-)

While Brian McNamara (the writer of the story) itself thinks they should've removed the interface implementation, because now you have the change that abort is being called. Which isn't quite usefull in all cases.

# re: WCF Service Proxy Helper

Tuesday, January 02, 2007 5:17 AM by Dennis van der Stelt

Aaah, seeing this example makes things much clearer! :)

using (CalculatorClient client = new CalculatorClient())

{

   ...

   throw new ApplicationException("Hope this exception was not important, because "+

                                  "it might be masked by the Close exception.");

} // <-- this line might throw an exception.

# Usage of the WCF ServiceProxyHelper

Tuesday, January 30, 2007 1:47 AM by Erwyn van der Meer

I received a question through the contact form about the usage of my WCF ServiceProxyHelper . That blog

# re: WCF Service Proxy Helper

Wednesday, June 27, 2007 11:40 AM by WCFhelp

Can u tell me why the communication goes to faulted state? All blogs its mentioned,  it is in a faulted state. But nobody explains why?

# re: WCF Service Proxy Helper

Monday, July 30, 2007 2:37 AM by Dave Ferguson

There are many reasons that the proxy can go into a faulted state.  The simplest reason is that the service went down and the client side dispatcher couldn't connect to the service.  Another reason is that the service is poorly coded and threw an unhandled exception instead of wrapping an exception in FaultException<T>.  Suffice to say, that any abnormal operation that happens can cause the proxy to become faulted.  Because of this, you should always catch FaultException<T>, FaultException, and CommunicationException in that order (see msdn2.microsoft.com/.../ms733912.aspx for an example).

# re: WCF Service Proxy Helper

Tuesday, August 21, 2007 7:16 AM by Corneliu I. Tusnea

Erwyn,

Here is a small utility class that will emit proxies and wrappers for WCF services for you at runtime and does all the delegation back to the proxy on the fly (with no reflection and no performance hit).

www.acorns.com.au/.../Building+a+reusable+ClientBase+proxy.aspx

Regards,

Corneliu.