In our external boundaries that expose WCF services, we convert all internal exceptions to FaultException
. This is a manual process which often has minor flaws unique to each implementation. It has been copy/pasted and mindlessly modified (or forgotten) for each exposed method. To reduce the errors, I wanted to create an aspect which would catch any unhandled exception.
We do a mapping of internal exceptions to fault exceptions. How can I send a mapping function to the aspect?
If I add a property to the aspect like this:
[Serializable]
public sealed class FaultExceptionConverter : OnExceptionAspect {
public Func<Exception, FaultException> FaultConverter { get; set }
}
I cannot (as expected by Attribute restrictions) initialize it like [FaultExceptionConverter(FaultConverter = MyConversionMethod)]
(where MyConversionMethod
is some method assignable to Func<Exception, FaultException>
). Is there any pattern for passing this type of parameter to the aspect? Many types can be passed into aspects. Is this a common problem?
If there happens to be a better way to accomplish this, I would appreciate the advice.
I've encountered similar frustrating limitations in aspect implementation, and one approach I've used to get around them is to have the aspect treat the class it is implemented on as some 'provider' type, which it can callback on to request other bits at runtime.
So, in your case, I imagine an OnException override that looks something like;
public override void OnException(MethodExecutionArgs args)
{
IFaultConverterProvider provider = args.Instance as IFaultConverterProvider;
if (null != provider)
Func<Exception, FaultException>exceptionConverterFunc = provider.GetFunc();
}
Where IFaultConverterProvider
is some interface you define and implement on the attributed type to provide the extra parameters you are missing.
Then, as a bit of a sanity check, you can introduce some compile-time validation into your aspect to ensure that the type it is applied to actually implements this required interface;
public override bool CompileTimeValidate(Type type)
{
if (!type.IsImplementationOf(typeof(IFaultConverterProvider )))
{
// The aspect must be in a type which implements IFaultConverterProvider
Message.Write(
MessageLocation.Of(type),
SeverityType.Error,
"CUSTOM02",
"Cannot apply [MyFaultExceptionAspect] to type {0} because it does not implement IFaultConverterProvider .", type);
return false;
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With