WCF Exception shielding always instancing all fault contracts?

Topics: Building and extending application blocks, Exception Handling Application Block
Jul 23, 2008 at 11:08 AM

I have a question regarding WCF Exception Shielding, if anyone can help. I have created a custom implementation of IExceptionHandler, because I needed more control over properties mapping than the provided FaultContractExceptionHandler could give. My class is basicly a copy of EntLib's FaultContractExceptionHandler (along with FaultContractExceptionHandlerData) with some modifications to the PopulateFaultContractFromException method and its helper methods. I've updated my configuration to instantiate the custom FaultContractExceptionHandler instead of EntLib's and the exception shielding is working great. But yesterday, while I was debugging some other issues I noticed that during exception shielding the Assemble method of FaultContractExceptionHandlerData class is being called once for every FaultContract registered in the configuration. Since it is being called from external code I guess that Entlib is doing this. Haven't really had the time to dig into it (no VS2008 to debug Entlib) so I hope that someone has already stumbled upon this.

Basicly, what happens is this. If I have 3 mappings between exceptions and faults in the configuration, no matter what exception is being thrown the Assemble() method below gets executed 3 times, once for every registered fault contract, which means that the constructor of my extended class is also being called 3 times. I would expect it to happen perhaps the first time an exception is encountered or simply just once based on the type of the exception being thrown, but this goes on for every exception. When I finish my work with this, there will probably be some 30 or 40 exception-to-fault mappings and I am concerned how this will impact the service performance. 

// from my FaultContractExceptionHandlerData.cs.
public IExceptionHandler Assemble(IBuilderContext context, ExceptionHandlerData objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
FaultContractExceptionHandlerData castedObjectConfiguration = (FaultContractExceptionHandlerData)objectConfiguration;
FaultContractExceptionHandlerExtended createdObject= new FaultContractExceptionHandlerExtended(Type.GetType(castedObjectConfiguration.FaultContractType),castedObjectConfiguration.ExceptionMessage,castedObjectConfiguration.Attributes);
return createdObject;


Can someone confirm that this happens also with the default FaultContractExceptionHandler, is this expected behaviour? Am I worrying for nothing?

Thanks in advance!

Jul 23, 2008 at 12:49 PM


Yes, this is the expected behavior.



Jul 23, 2008 at 1:48 PM

thank you for the quick answer! Looks like I am going to have to live with this, then.

Just out of curiosity, this behavior is by design then? If you can spare a few more minutes, can you shed some more light on this, please? I would like to know why this works the way it does and perhaps whether it can be optimized somehow. I don't expect it to be a problem right away but I am not sure about the performance impact later on when there will be many more contracts and would like to be prepared for a "plan B", if the need arises.

Thanks in advance!
Jul 23, 2008 at 10:29 PM

I honestly don't know the reason for the current design. I agree there's room for improvement.

I think that mixing WCF shielding with normal exception handling is not optimal in all cases. The shielding handler acts as a beefed up replace handler that throws an temporary exception, which is in turn caught by the shielding error handler to extract the mapped fault; you need to set up the policy just right for this to work (make sure you don't add a wrap or replace handler after the shielding handler that hides the temporary exception, make sure you set up the exception type to throw the new exception) and there's no way to make sure you're using the handler in a policy intended for shielding. You may want to set up a new behavior/error handler combination that reuses the fault contract mapping behavior without going through the generic exception handling support.