A Generic, IDisposable WCF Service Client

I've done better! An improved service client wrapper is described here.

WCF clients need to be cleaned up properly, but as they're usually auto-generated they don't implement IDisposable. I've been doing a fair bit of WCF work recently, so I wrote a generic WCF client wrapper which effectively gives me a disposable service client.

The ServiceClientWrapper is constructed using a WebServiceConfig instance, which contains a Binding, an EndPointAddress, and whether the client should ignore SSL certificate errors - pretty useful during testing! The Binding can be created based on configuration data or entirely programmatically - that's not the client's concern.

Here's the service client code:

using System;
using System.Net;
using System.Net.Security;
using System.ServiceModel;

public class ServiceClientWrapper<TClient, IService> : IDisposable
    where TClient : ClientBase<IService>
    where IService : class
{
    private readonly WebServiceConfig _config;
 
    private TClient _serviceClient;
 
    public ServiceClientWrapper(WebServiceConfig config)
    {
        this._config = config;
    }
 
    public TClient CreateServiceClient()
    {
        this.DisposeExistingServiceClientIfRequired();
 
        if (this._config.IgnoreSslErrors)
        {
            ServicePointManager.ServerCertificateValidationCallback =
                (obj, certificate, chain, errors) => true;
        }
        else
        {
            ServicePointManager.ServerCertificateValidationCallback =
                (obj, certificate, chain, errors) => errors == SslPolicyErrors.None;
        }
 
        // Or you can use:
        // this._serviceClient = (TClient)typeof(TClient).GetInstance(
        //     this._config.Binding,
        //     this._config.Endpoint);
        this._serviceClient = (TClient)Activator.CreateInstance(
            typeof(TClient),
            this._config.Binding,
            this._config.Endpoint);
 
        if (this._config.ClientCertificate != null)
        {
            this._serviceClient.ClientCredentials.ClientCertificate.Certificate =
                this._config.ClientCertificate;
        }
 
        return this._serviceClient;
    }
 
    public void Dispose()
    {
        this.DisposeExistingServiceClientIfRequired();
    }
 
    private void DisposeExistingServiceClientIfRequired()
    {
        if (this._serviceClient != null)
        {
            try
            {
                if (this._serviceClient.State == CommunicationState.Faulted)
                {
                    this._serviceClient.Abort();
                }
                else
                {
                    this._serviceClient.Close();
                }
            }
            catch
            {
                this._serviceClient.Abort();
            }
 
            this._serviceClient = null;
        }
    }
}

A client for a particular service can then be created something like this:

public class ManagementServiceClientWrapper :
    ServiceClientWrapper<ManagementServiceClient, IManagementService>
{
    public ManagementServiceClientWrapper(WebServiceConfig config)
        : base(config)
    {
    }
}

...or with an alias in the using list (if you don't need a reusable class):

using ManagementServiceClientWrapper =
    ServiceClientWrapper<ManagementServiceClient, IManagementService>;

...where ManagementServiceClient is the auto-generated client class, and the IManagementService is the auto-generated WCF service interface - and used like this:

using (var serviceClientWrapper = new ManagementServiceClientWrapper(config))
{
    serviceClientWrapper.CreateServiceClient().CallService();
}

The underlying WCF client created by the CreateServiceClient() call will be disposed after the using(), and hey presto - a disposable WCF service client.

Edit: I've added an example application using the client at https://bitbucket.org/MrSteve/wcfserviceclientexample.

Print | posted @ Thursday, June 30, 2011 8:18 PM

Comments on this entry:

Gravatar # re: A Generic, IDisposable WCF Service Client
by paul at 10/31/2011 2:29 PM

Hey there,

This is a great post!

Could you please share the source code?

Regards,
Paul.
Gravatar # re: A Generic, IDisposable WCF Service Client
by Steve at 10/31/2011 8:49 PM

Thanks, Paul! By 'source code', d'you mean a sample project using the class?
Gravatar # re: A Generic, IDisposable WCF Service Client
by paul at 11/1/2011 7:50 AM

Hi Steve:

I would particularly like to have a look at the source code in 'WebServiceConfig'. No need for a sample project as the post is clear enough.

Thank you,
Paul.
Gravatar # re: A Generic, IDisposable WCF Service Client
by Steve at 11/1/2011 10:02 PM

Ah, ok - well I'll tell you what - I've made a very quick example application anyway. It's at https://bitbucket.org/MrSteve/wcfserviceclientexample - the WebServiceConfig source is at https://bitbucket.org/MrSteve/wcfserviceclientexample/src/fe7f21a91263/Program/WebServiceConfig.cs :)
Post A Comment
Title:
Name:
Email:
Comment:
Verification: