Geeks With Blogs
MOAR Objects Steve Wilkes' blog on .NET, Agile, TDD, design patterns and all that jazz

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.

Posted on Thursday, June 30, 2011 8:18 PM | Back to top


Comments on this post: A Generic, IDisposable WCF Service Client

# re: A Generic, IDisposable WCF Service Client
Requesting Gravatar...
Hey there,

This is a great post!

Could you please share the source code?

Regards,
Paul.
Left by paul on Oct 31, 2011 2:29 PM

# re: A Generic, IDisposable WCF Service Client
Requesting Gravatar...
Thanks, Paul! By 'source code', d'you mean a sample project using the class?
Left by Steve on Oct 31, 2011 8:49 PM

# re: A Generic, IDisposable WCF Service Client
Requesting Gravatar...
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.
Left by paul on Nov 01, 2011 7:50 AM

# re: A Generic, IDisposable WCF Service Client
Requesting Gravatar...
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 :)
Left by Steve on Nov 01, 2011 10:02 PM

Your comment:
 (will show your gravatar)


Copyright © Steve Wilkes | Powered by: GeeksWithBlogs.net | Join free