Category Archives: WCF

Testing that all Fault Exceptions are being handled in a WCF client

One of the things that the .Net compiler won’t warn developers about, is when another developer decides to add a new FaultException type and the client code isn’t updated to handle this new type of exception. The solution I’m demonstrating here is a generic solution to check for this, but implies that the client is going through a ChannelFactory and not a ClientBase implementation.

ChannelFactory implementations are usually better if there’s full ownership, in the institution, of service and clients. The share of the service contracts will allow Continuous Integration builds to fail if there was a breaking change made on the service that broke one or more of the consuming clients. You may argue that ChannelFactory implementations have the issue that if you change the service, with a non-breaking change, you need to re-test and re-deploy all your clients code: This isn’t exactly true, as if it is a non-breaking change, all the clients will continue to work even with a re-deploy of the service.

Default ChannelFactory Wrapper

The generic implementation depends on our default WcfService wrapper for a ChannelFactory. This could be abstracted through an interface that had the Channel getter on it, and make the generic method depend on the interface instead of the actual implementation.

I will provide here a simple implementation of the ChannelFactory wrapper:


public class WcfService<T> : IDisposable where T : class
{
private readonly object _lockObject = new object();
private bool _disposed;
private ChannelFactory<T> _factory;
private T _channel;
internal WcfService()
{
_disposed = false;
}
internal virtual T Channel
{
get
{
if (_disposed)
{
throw new ObjectDisposedException("Resource WcfService<" + typeof(T) + "> has been disposed");
}
lock (_lockObject)
{
if (_factory == null)
{
_factory = new ChannelFactory<T>("*"); // First qualifying endpoint from the config file
_channel = _factory.CreateChannel();
}
}
return _channel;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
internal void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (!disposing)
{
return;
}
lock (_lockObject)
{
if (_channel != null)
{
try
{
((IClientChannel)_channel).Close();
}
catch (Exception)
{
((IClientChannel)_channel).Abort();
}
}
if (_factory != null)
{
try
{
_factory.Close();
}
catch (Exception)
{
_factory.Abort();
}
}
_channel = null;
_factory = null;
_disposed = true;
}
}
}

view raw

gistfile1.cs

hosted with ❤ by GitHub

Example of a client using the Wrapper

Here’s an example of code that we want to test, for a client that’s using the WcfService wrappe. The separation from the method that creates the WcfService wrapped in a using clause and the internal static one is just for testing purposes, just so we can inject a WcfService mock and assert against it. The client successfully wraps a FaultException into something meaningful for the consuming application.


public class DocumentClient : IDocumentService
{
public string InsertDocument(string documentClass, string filePath)
{
using (var service = new WcfService<IDocumentService>())
{
return InsertDocument(documentClass, filePath, service);
}
}
internal static string InsertDocument(string documentClass, string filePath, WcfService<IDocumentService> service)
{
try
{
return service.Channel.InsertDocument(documentClass, filePath);
}
catch (FaultException<CALFault> ex)
{
throw new DocumentCALException(ex);
}
catch (Exception ex)
{
throw new ServiceUnavailableException(ex.Message, ex);
}
}
}

view raw

gistfile1.cs

hosted with ❤ by GitHub

The generic Fault contract checker

This implementation is using Moq as the Mocking framework and the code is dependent on it. It also provides signatures up to 4 exceptions that are expected, this is done with a Top-Down approach, where the signature with the most type parameters has the full implementation and the others just call the one that’s one higher level in the signature chain. To support this mind set, a special empty DummyException is declared to fill the gaps between Type Parameters in the different signatures.

Breaking down the code, what it is doing is creating a dynamic Expression Tree that we can wire in the Setup method of the client mock that will intercept calls with any type of parameter (It.IsAny). Then for each FaultContractAttribute that is decorating the service, instantiate it and wire everything so that the service method is setup to throw it. Finally call it, and check if it was caught and wrapped or if we are getting the original FaultException back.


public static class ContractCheckerExtension
{
public static string CheckFaultContractMapping<TContract, TEx1>(this MethodInfo method, Action<Mock<WcfService<TContract>>> action)
where TContract : class
where TEx1 : Exception
{
return method.CheckFaultContractMapping<TContract, TEx1, DummyException>(action);
}
public static string CheckFaultContractMapping<TContract, TEx1, TEx2>(this MethodInfo method, Action<Mock<WcfService<TContract>>> action)
where TContract : class
where TEx1 : Exception
where TEx2 : Exception
{
return method.CheckFaultContractMapping<TContract, TEx1, TEx2, DummyException>(action);
}
public static string CheckFaultContractMapping<TContract, TEx1, TEx2, TEx3>(this MethodInfo method, Action<Mock<WcfService<TContract>>> action)
where TContract : class
where TEx1 : Exception
where TEx2 : Exception
where TEx3 : Exception
{
return method.CheckFaultContractMapping<TContract, TEx1, TEx2, TEx3, DummyException>(action);
}
public static string CheckFaultContractMapping<TContract, TEx1, TEx2, TEx3, TEx4>(this MethodInfo method, Action<Mock<WcfService<TContract>>> action)
where TContract : class
where TEx1 : Exception
where TEx2 : Exception
where TEx3 : Exception
where TEx4 : Exception
{
// we're creating a lambda on the fly that will call on the target method
// with all parameters set to It.IsAny<[the type of the param]>.
var lambda = Expression.Lambda<Action<TContract>>(
Expression.Call(
Expression.Parameter(typeof (TContract)),
method,
CreateAnyParameters(method)),
Expression.Parameter(typeof (TContract)));
// for all the fault contract attributes that are decorating the method
foreach (var faultAttr in method.GetCustomAttributes(typeof(FaultContractAttribute), false).Cast<FaultContractAttribute>())
{
// create the specific exception that get's thrown by the fault contract
var faultDetail = Activator.CreateInstance(faultAttr.DetailType);
var faultExceptionType = typeof(FaultException<>).MakeGenericType(new[] { faultAttr.DetailType });
var exception = (FaultException)Activator.CreateInstance(faultExceptionType, faultDetail);
// mock the WCF pipeline objects, channel and client
var mockChannel = new Mock<WcfService<TContract>>();
var mockClient = new Mock<TContract>();
// set the mocks
mockChannel.Setup(x => x.Channel)
.Returns(mockClient.Object);
mockClient.Setup(lambda)
.Throws(exception);
try
{
// invoke the client, wrapped in an Action delegate
action(mockChannel);
}
catch (Exception ex)
{
// if we get a targeted exception it's because the fault isn't being handled
// and we return with the type of the fault contract detail type that was caught
if (ex is TEx1 || ex is TEx2 || ex is TEx3 || ex is TEx4)
return faultAttr.DetailType.FullName;
// else soak all other exceptions because we are expecting them
}
}
return null;
}
private static IEnumerable<Expression> CreateAnyParameters(MethodInfo method)
{
return method.GetParameters()
.Select(p => typeof (It).GetMethod("IsAny").MakeGenericMethod(p.ParameterType))
.Select(a => Expression.Call(null, a));
}
}
[Serializable]
public class DummyException : Exception
{
}

view raw

gistfile1.cs

hosted with ❤ by GitHub

Here’s a sample of a unit test using the ContractChecker for the example client showed previously in the post:


[TestMethod]
public void Ensure_InsertDocument_FaultContracts_AreAllMapped()
{
var targetOperation = typeof (IDocumentService).GetMethod(
"InsertDocument",
new[]
{
typeof (string),
typeof (string)
});
var result = targetOperation.CheckFaultContractMapping<IDocumentService, ServiceUnavailableException>(
m => DocumentClient.InsertDocument(string.Empty, string.Empty, m.Object));
Assert.IsNull(result, "The type {0} used to detail a FaultContract isn't being properly handled on the Service client", result);
}

view raw

gistfile1.cs

hosted with ❤ by GitHub

Dispatcher is long gone, say bye to TaskScheduler and hello to async!

In the old days of TaskScheduler

When .Net 4.0 come out, WPF developers went from using the old Dispatcher and the BeginInvoke to using the TaskScheduler with Tasks. Some new patterns emerged, teams started to inject the WPF scheduler on DI containers and life was good for everyone. This design was particularly better for Junior developers, less space to do mistakes.

Then async showed up

With .Net 4.5, we have the async and await programming model, this is essentially the compiler breaking down methods and method calls into Tasks for us, giving us an easier programming model, with less code noise, that effectively does the same.

The use of async requires things that are “awaitable”, and some frameworks aren’t ready for this yet, for example EntityFramework. But since the early days of the async CTP, this has been a widely accepted change, so work is being done to support async across a wider range of frameworks and modules.

How to use async in a WPF – WCF context

I did a common setup for WPF applications, there’s a WCF Service, very simple that is the Service template with 2 extra lines:
The Interface:

[ServiceContract]
public interface IService
{
    [OperationContract]
    string GetData();
}

The Implementation:

public class Service : IService
{
    public string GetData()
    {
        Thread.Sleep(5000);
        return "some data";
    }
}

This Service has a Thread.Sleep of 5 seconds in it, to simulate some amount of work. On the WPF side the application is very simple, it’s 2 buttons, one to “Start” and a second one that is disabled called “Ready” that does nothing when pressed. The start button does the call to the service, and once over it enables the Ready button.
blog3
This is defined in XAML as:

<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
    <Button Width="100" Click="StartClick">Start</Button>
    <Button Name="ReadyButton" Width="100" IsEnabled="False" Margin="0 20 0 0">Ready</Button>
</StackPanel>

The Service is added to the WPF application as a normal Service Reference out of the box. If we look at the Reference.cs of the Service we can see the 2 calls to our method “GetData” that are available:

public string GetData() {
    return base.Channel.GetData();
}
        
public System.Threading.Tasks.Task<string> GetDataAsync() {
    return base.Channel.GetDataAsync();
}

The top one is the normal synchronous call while the bottom one is the async version of it, and it’s already returning in the form of Task<T> that await requires.

On the code behind of the Window that’s hosting the buttons we just add a Click event handler for the Start button and make it async. Inside we add the necessary code to call GetData on the client and make sure that the call awaits the result:

private async void StartClick(object sender, System.Windows.RoutedEventArgs e)
{
    using (var client = new ServiceClient())
    {
        var someData = await client.GetDataAsync();
        ReadyButton.IsEnabled = true;
    }
}

As you can see, the programming model is very clean, very easy to use. And if you use it correctly you won’t run into the usual WPF problems of making sure that you update the UI only on the WPF thread either trough the Dispatcher or the right TaskScheduler. The code that is outside the await will run in the WPF thread, while the call to the “awaitable” GetData will run in a separate thread, thus the Button.IsEnabled = true will run smoothly on the WPF thread.

If you are using Resharper you get a nice warning when writing async methods and you’re not awaiting anything (which means the method will run synchronously).

blog4