Stephen Patten
Stephen Patten

Reputation: 6363

How to Correctly Invoke WCF ServiceClient Proxy Extensions?

While troubleshooting a wcf client issue I came across some code from @marc-gravell here. I read the article a number of times and then decided to try and see if I could use the code for real so I created a console app and pulled it all in.

Wrapper:

public interface IDisposableWrapper<T> : IDisposable
{
    T BaseObject { get; }
}

public class DisposableWrapper<T> : IDisposableWrapper<T> where T : class, IDisposable
{
    public T BaseObject { get; private set; }
    public DisposableWrapper(T baseObject) { BaseObject = baseObject; }
    protected virtual void OnDispose()
    {
        BaseObject.Dispose();
    }
    public void Dispose()
    {
        if (BaseObject != null)
        {
            try
            {
                OnDispose();
            }
            catch
            {
                // swallow...
            }
        }
        BaseObject = null;
    }
}

Extensions:

public static class DisposableExtensions
{
    // core "just dispose it without barfing"
    public static IDisposableWrapper<T> Wrap<T>(this T baseObject)
        where T : class, IDisposable
    {
        if (baseObject is IDisposableWrapper<T>) return (IDisposableWrapper<T>)baseObject;
        return new DisposableWrapper<T>(baseObject);
    }

    // specific handling for service-model
    public static IDisposableWrapper<TProxy> Wrap<TProxy, TChannel>(this TProxy proxy)
        where TProxy : ClientBase<TChannel>
        where TChannel : class
    {
        return new ClientWrapper<TProxy, TChannel>(proxy);
    }
}

ClientWrapper:

public class ClientWrapper<TProxy, TChannel> : DisposableWrapper<TProxy>
    where TProxy : ClientBase<TChannel>
    where TChannel : class
{
    public ClientWrapper(TProxy proxy) : base(proxy)
    {
    }

    protected override void OnDispose()
    {
        // lots of code per state of BaseObject
        //State != CommunicationState.Faulted;
    }
}

Now, when I go to use it, I have this:

static void Main(string[] args)
{

    using (var proxy = new PLPlacementServiceClient())
    {
        var result = proxy.GetDocumentClassForNewBusiness();
    }

    using (var proxy = new PLPlacementServiceClient().Wrap())
    {
        var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
    }

    using (var proxy = new PLPlacementServiceClient().Wrap<>())//what goes here?
    {
        var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
    }

}

When I F-12 the PLPlacementServiceClient().Wrap() method , it takes me to the non-generic implementation in the extensions class

IDisposableWrapper<T> Wrap<T>(this T baseObject)

, but I was expecting to be taken to the other signature

IDisposableWrapper<TProxy> Wrap<TProxy, TChannel>(this TProxy proxy)

So here is my question(s), "How do I invoke the ClientBase version of the extension?"

Thank you, Stephen

Upvotes: 1

Views: 81

Answers (1)

Jan Muncinsky
Jan Muncinsky

Reputation: 4408

You must specify both type parameters for method Wrap. That is:

using (var proxy = new PLPlacementServiceClient().Wrap<PLPlacementServiceClient,/*type of the service contract PLPlacementServiceClient is implementing*/>())
{
    var result = proxy.BaseObject.GetDocumentClassForNewBusiness();
}

Upvotes: 1

Related Questions