Skip to content

Disposable wrapper for WCF clients

When a WCF client calls a service and the call throws an exception (no FaultException, that's fine), then calling Close() or Dispose() on that client will throw another Exception because the client is in the faulted state. The correct way to "dispose" or cleanup a faulted client is to call Abort(). This means that we can't embed the WCF client in a using-statement because that will always dispose the client.

The correct way would be

ServiceClient myClient = new ServiceClient();
try
{
myClient.DoSomething();
myClient.Close();
}
catch
{
myClient.Abort();
// error handling or throw;
}

Because some of my projects use a lot of WCF calls, this pattern is too tedious for me. Instead I wrote a simple wrapper:

using System;
using System.ServiceModel;

public class GenericProxy<T> : ClientBase<T>, IDisposable
where T : class
{
public GenericProxy()
: base()
{
}

void IDisposable.Dispose()
{
if (State == CommunicationState.Faulted)
Abort();
else
Close();
}

public T Service
{
get
{
return Channel;
}
}
}

The only drawback is that instead of writing myClient.DoSomething() now I have to write myClient.Channel.DoSomething():

using (GenericProxy<IService> myClient = new GenericProxy<IService>())
{
myClient.Channel.DoSomething();
}

Signing assemblies with a key container

This article is a reference for me since I have to look it up all the time.

Since .NET 1.0 I prefer to sign my assemblies and to use a key container with a AssemblyKeyNameAttribute instead of having to define the path of a key file in each assembly:

[assembly: AssemblyKeyName("myKeyName")]

Starting with .NET 2.0/Visual Studio 2005 this generates the compiler warning CS1699 (or an unnumbered warning for VB.NET). For my projects I always enable "Treat warnings as errors". For C# I can add 1699 to the suppressed warnings in the project settings, but I can't find a way to suppress the warning in the VB.NET project settings.

Instead I have to edit the .vbproj-file with a text editor and add somewhere in the first PropertyGroup element the line

<KeyContainerName>myKeyName</KeyContainerName>

Unfortunately Microsoft didn't add a project setting to use assembly key containers.