2
\$\begingroup\$

Background information

I am building a web application that consumes 3 different WCF services that are hosted internally.

Each response object from the service inherits from a base class ResponseBase. This class contains properties int ErrorCode and string ErrorMessage.

When I am consuming these services in my web application I want to implement some general error handling that verifies if the response object contains an errorcode < 0.

What I've come up with is a static class ServiceHelper with several overloads of the following method:

public static void VerifyResponse(dynamic response)
{
    if (response == null) throw new ArgumentNullException("response");

    if (response.ErrorCode < 0)
        throw new InvalidServiceResponseException(response.ErrorCode, response.ErrorMessage);
}

Now as you can see the type of the parameter is dynamic. The reason for this, and this is basically why I'm asking this question, is that I don't have a general base object to define all response objects. Because each WCF service will creat its own contracts there can't be a shared base object between services. Well... it can be done but we prefer to keep it simple for now.

Question

Do you of some magic way to validate 3 different types of response objects but with a properly typed parameter and without creating a different method for each service. Because each service has a different ResponseBase type even though it is actually the same.

Or do you think it is permitted to use a dynamic parameter in this context?

\$\endgroup\$
2
  • \$\begingroup\$ Well, some things cannot be done right and easy at the same time :) I recommend you reading that article. It won't make your implementation easier, but I am sure it will shed some light on how to organize work with WCF services better. \$\endgroup\$ – Sergei Dec 16 '11 at 5:42
  • \$\begingroup\$ Thanks for the article, It provides some alternatives. But keeping maintainability and KISS in mind, I think my current solution isn't so bad. \$\endgroup\$ – Peter Dec 16 '11 at 7:37
2
\$\begingroup\$

Peter - a couple of observations:

  1. Since you say "Each response object from the service inherits from a base class ResponseBase" the gut reaction is to just use ResponseBase and let the inheritance model in C# handle everything. As you go on to explain, however, ResponseBase is not really the same base class across services, as they vary from service to service with generated code. In this case, you know exactly what the shape of the object is, but don't know its type. This is an example of 'duck typing' - if it looks like a duck, walks like a duck, and quacks like a duck, then we might as well treat it like a duck. This is exactly what dynamic typing is good for and seems to me an excellent use of this feature of C# 4.0.
  2. The two exception conditions in your code are not created equal. The first seems to flag an incorrect use of the method, while the second is the method doing its job. So consider replacing the first one with a Code Contract if you are on .NET 4. (See Dino Esposito's articles in MSDN Magazine - 3 months in a row - for a good overview, starting here. Note especially that Code Contracts can be turned off for runtime, and they may be off already in your project. See Dino's articles for an explanation.)

Here is pseudocode:

public static void VerifyResponse(dynamic response) 
{
   Contract.Requires(response != null);
   // or perhaps: Contract.Requires<ArgumentNullException>(response != null, "response");
   // or: if (response == null) throw new ArgumentNullException("response"); 

   if (response.ErrorCode < 0) 
      throw new InvalidServiceResponseException(response.ErrorCode, response.ErrorMessage); 
}
\$\endgroup\$
3
  • \$\begingroup\$ please reread the text below my code example in the question. \$\endgroup\$ – Peter Jan 16 '12 at 11:28
  • \$\begingroup\$ @Peter - good point! I rewrote bullet 1. of my answer after re-reading the text below your code example. Bullet 2. still applies. \$\endgroup\$ – codingoutloud Feb 5 '12 at 0:05
  • \$\begingroup\$ Thanks for teaching me about the Contract class and pointing me to Code Contracts in general! Really helpful. And for approving my use of dynamic types in this case :-) \$\endgroup\$ – Peter Feb 6 '12 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.