WCF Exception throwing and handling the OOP way
Ok, so I have asked another question on the same topic here and while I did not get a direct answer there I've pulled together some code that I got working to do what I wanted. Question is, does this way break some OOP principle?
What I wanted
- Use proper OOP to declare fault types on a service
- Have one catch block in the client side that can handle multiple types of exceptions thrown from the service
- Have one HandleException method per fault class that has its own implementation
- On the client side have just one exception block understand what exception was thrown and call the respective HandleException method from the corresponding fault class
How I got it working
Declared a fault contract on server for each exception type that inherits from a base exception type
[DataContract] public class BusinessRuleViolationFault : BaseFault { public BusinessRuleViolationFault(string message) : base(message) { } }
[DataContract]
public class SomeOtherViolationFault : BaseFault
{
public SomeOtherViolationFault(string message)
: base(message)
{
}
}
[DataContract]
public abstract class BaseFault
{
public BaseFault(string message) { Message = message; }
}
On the client side I created partial classes of the same fault types as above and implemented the handle exception method in it. I had to do this on the client side since if I created this method on the service side it would not get serialized and be available via the proxy.
public partial class BusinessRuleViolationFault : BaseFault
{
public override void HandleException()
{
MessageBox.Show("BusinessRuleViolationFault handled");
}
}
public partial class SomeOtherViolationFault : BaseFault
{
public override void HandleException()
{
MessageBox.Show("SomeOtherViolationFault handled");
}
}
public abstract partial class BaseFault
{
public abstract void HandleException();
}
Then created an extension method on the faultexception class as per Christians code which I have marked as accepted answer in my previous post. This basically used reflection to get me the name of the fault exception class that was thrown.
Then in my client catch block I used that name to create an instance of the locally created partial class which has the handle exception method.
开发者_Go百科What I am curious to know is, have I broken some OOP principle here? Is this OOP at all?
I dont want multiple if else statement in this one catch block or have multiple catch blocks. What is your opinion on the tradeoff of using one catch block to gain performance and lose it with reflection by trying to figure out what class method to call?
Thanks for your time and patience ...
I don't understand exactly why reflection is needed here (as described in the previous posted question). I simply do this in my code and it works fine:
try
{
proxy.CallServiceMethod(message);
}
catch (Exception e)
{
if (e is FaultException<BaseFault>)
{
BaseFault exceptionToHandle =
(e as FaultException<BaseFault>).Detail as BaseFault;
exceptionToHandle.HandleException();
}
}
Aside from the unnecessary reflection, I don't see anything wrong with the way you have implemented this (from an OOP point of view at least).
精彩评论