To cut a long story short...
I want my clients (client as in "service consumer", e.g. REST) to get status information about what the business layer did or failed to do. Just returning a null object or just null is not exactly very descriptive. Anything might have happened.
Damn it - I made such a nice UML sequence diagram to illustrate the problem but StackOverflow won't let me post it due to insufficient reputation points :'(
The problem is probably the oldest in the world. However I didn't find a satisfying answer to it. I could settle for the solution described here How Do You Communicate Service Layer Messages/Errors to Higher Layers Using MVP? but it doesn't make me jump through loops. Throwing exceptions all over the place doesn't sound like a good thing to do. Exceptions are expensive after all. Also I'd need to create an Exception for quite a lot of "this might happen" scenarios.
****So the question is... do you design "Generic Return Values" or throw Exceptions?****
Unfortunately I didn't find an answer to that so far... this is where you come into play :)
I'd go ahead and put a status code, a message and the actual requested information of type T in it. Let's assume this generic return value is "ServiceResult".
Considerations I made:
- Ok so my business layer methods all return ServiceResult objects. Good.
- That is very easy to work with - providing that all your business layer magic happens in the one public method you call. Well - it doesn't. Not typically.
- So you would either have to make the ServiceResult accessible to all private methods as well or pass it around as a parameter. You don't want to pass it around a 100 times... trust me.
- That's when you decide to add a ServiceResult property to your "controling" business class. But wait.. you don't add generic properties in c#. Because it's not a supported feature.
- What is next? Using "object" as a property instead? Hardly... you don't want to cast all the time and you wouldn't know what to cast to in the first place because T could be anything. And you private method (3 levels down from the public method you initially called) simply doesn't know the type - of course you could make that a property of your class as well. It's still bad design I guess..
- Assuming you solved that problem you'd need to check the ServiceResult.Status every time before the next method is invoked if the ServiceResult isn't already in a "faulted" state and further processing is useless. Of course you could put all that magic in a Run(Func func) method but if you are at this point... at the latest... you start considering using Exceptions again :)
Basically that's why I think people just throw exceptions and catch them at the highest level (within your business logic - not in the controller).
Is there a design patterns to this problem which I am not aware of?