Click here to Skip to main content
15,891,687 members
Articles / WCF

Mmmmm… Clean, Sweet WCF Proxy Usage with TidyProxy!

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
12 Apr 2010CPOL1 min read 10.6K   4
Clean, sweet WCF proxy usage with TidyProxy

Everyone knows (hopefully) how WCF has made multi-tiered application development easier and cleaner. You get nicely generated client proxies that reuse common libraries straight out of Visual Studio – no more having to convert between your DTOs and the Web Service DTOs. They even implement IDisposable - you can just wrap them in using statements and you’re good to go! How neat is that!

C#
1: using (var proxy = new TidyProxy<SomeWCFServiceClient>())
2: {
3:    proxy.Client.DoSomeMagicallyComplexOperation();
4: }

But only if nothing goes wrong.

If the service you’re calling throws an exception (or Faults), then the Client's dispose method will throw another exception – masking the actual problem… There’s an entire MSDN article on the issue. The suggested fix? Replace the using block above with something like this:

C#
 1: var client = new SomeWCFServiceClient();
 2: try
 3: {
 4:     client.DoSomeMagicallyComplexOperation();
 5:     client.Close();
 6: }
 7: catch (CommunicationException e)
 8: {
 9:     client.Abort();
10: }
11: catch (TimeoutException e)
12: {
13:     client.Abort();
14: }
15: catch (Exception e)
16: {
17:     client.Abort();
18:     throw;
19: }

WCF not looking so sweet now, is it?

Now, I’ve got an issue with this type of boilerplate code, it’s verbose and awkward and reeks of having to clean up someone else's mess. So, what can we do about? Well, there’s a couple of good ideas out there from replacing the default ClientBase to adding an additional partial class to the generated code. These are good solutions, but will require modification of the generated code and I’m too lazy to do that for each service I’m consuming.

So, I want a way to leverage the existing, generated client and keep the implementation as close to the neat using statement as possible. Thankfully, through the wonders of Generics and the Adapter pattern WCF can be redeemed – here’s TidyProxy:

C#
 1: using System;
 2: using System.ServiceModel;
 3: namespace MartinOnDotNet.Helpers.WCF
 4: {
 5:     /// <summary>
 6:     /// A disposable wrapper that can be used to remove a lot of
        /// the WCF boiler plate code
 7:     /// </summary>
 8:     /// <typeparam name="TProxy">The type of the proxy.</typeparam>
 9:     public class TidyProxy<TProxy> : IDisposable where TProxy : ICommunicationObject,
            new()
10:     {
11:         private TProxy _client;
12:         /// <summary>
13:         /// Gets or sets the generated client.
14:         /// </summary>
15:         /// <value>The client.</value>
16:         public TProxy Client
17:         {
18:             get
19:             {
20:                 if (_client == null) _client = new TProxy();
21:                 return _client;
22:             }
23:             set
24:             {
25:                 _client = value;
26:             }
27:         }
28:
29:         #region IDisposable Members
30:         /// <summary>
31:         /// Performs application-defined tasks associated with freeing,
            /// releasing, or resetting unmanaged resources.
32:         /// </summary>
33:         public void Dispose()
34:         {
35:             if (_client == null) return;
36:             try
37:             {
38:                 if (_client.State == CommunicationState.Opened)
39:                 {
40:                     _client.Close();
41:                 }
42:                 else
43:                 {
44:                     _client.Abort();
45:                 }
46:             }
47:             catch (Exception ex)
48:             {
49:                 try
50:                 {
51:                     _client.Abort();
52:                 }
53:                 catch
54:                 {
55:                     // Nasty, but this error isn't the problem -
56:                     // the one that caused it is!
57:                 }
58:                 throw;
59:             }
60:             GC.SuppressFinalize(this);
61:         }
62:         #endregion
63:     }
64: }

So, what does this get me? Well, to call my magically complex service, I now just need to write:

C#
1: using (var proxy = new TidyProxy<SomeWCFServiceClient>())
2: {
3:   proxy.Client.DoSomeMagicallyComplexOperation();
4: }

Awesome!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Freestyle Interactive Ltd
United Kingdom United Kingdom
I'm a lead developer for Freestyle Interactive Ltd where we create many wonderful websites built on Microsofts ASP.Net and Ektron CMS.

I've been developing .Net applications (both Windows and Web) since 2002.

Comments and Discussions

 
QuestionIsn't it simplier ... ? Pin
jmix9012-Apr-10 20:08
jmix9012-Apr-10 20:08 
Hello,

I am wrong or you can do that just with an user extension ? Smile | :)

++
AnswerRe: Isn't it simplier ... ? Pin
Martin Jarvis12-Apr-10 20:15
Martin Jarvis12-Apr-10 20:15 
GeneralRe: Isn't it simplier ... ? Pin
jmix9012-Apr-10 23:05
jmix9012-Apr-10 23:05 
GeneralRe: Isn't it simplier ... ? Pin
Martin Jarvis12-Apr-10 23:10
Martin Jarvis12-Apr-10 23:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.