Kerri Brown
Kerri Brown

Reputation: 1187

Calling WCF service using extension method

I've written an extension method for use with WCF services that keeps all the disposal and exception handling logic in one place. The method is as follows:

public static TResult CallMethod<TChannel, TResult>(
    this ClientBase<TChannel> proxy,
    Func<TResult> func) where TChannel : class
{
    proxy.ThrowIfNull("proxy");
    func.ThrowIfNull("func");

    try
    {
        // set client credentials
        return func();
    }
    finally
    {
        if (proxy != null)
        {
            try
            {
                if (proxy.State != CommunicationState.Faulted)
                {
                    proxy.Close();
                }
                else
                {
                    proxy.Abort();
                }
            }
            catch (CommunicationException)
            {
                proxy.Abort();
            }
            catch (TimeoutException)
            {
                proxy.Abort();
            }
            catch (Exception)
            {
                proxy.Abort();
                throw;
            }
        }
    }
}

The method will be used like this:

public int CreateBusinessObject(BusinessObject item)
{
    MyServiceClient proxy = new MyServiceClient();
    return proxy.CallMethod(() => proxy.CreateBusinessObject(item));
}

My question really is whether this would be better as a static method which creates the service proxy? I'm slightly worried about my current implementation. Should the construction of the proxy be inside the try/catch? My current understanding is that if the constructor fails, there is nothing to dispose of anyway.

Upvotes: 3

Views: 1666

Answers (1)

Pieter van Ginkel
Pieter van Ginkel

Reputation: 29632

If the constructor fails, the entire object is in an invalid state. You should not be worried about disposing in this case.

A nice test for this is what would happen when you execute the following:

class Program
{
    static void Main(string[] args)
    {
        using (new TestClass())
        {
            Console.WriteLine("In using");
        }
    }

    class TestClass : IDisposable
    {
        public TestClass()
        {
            throw new Exception();
        }

        public void Dispose()
        {
            Console.WriteLine("Disposed");
        }
    }
}

The result is that the Disposing never gets reached. This is what happens when the constructor fails.

Upvotes: 2

Related Questions