Domanda

I have inherited a WCF service which acts as a file cache (each file representing the results of a request to a third party API). At the moment if the file doesn't exist the code creates a new request to create the data and it also raises an exception to the client code.

I think the idea is that the clients would come back to request the file again and by then it would be available by them (it takes a couple of seconds to generate the file).

I think there's a code smell here and I should rewrite this part. At the moment the exception is getting caught and bubbled up through a couple of methods. I think I should be establishing at source whether the file exists and pass that information up the call stack.

At the WCF interface I currently have a GetValue() method, though there are two options I think I could use to replace it:

  1. return null if the file does not exist.
  2. Use a bool TryGetValue(string key, out string value) method

Does anyone have any preferences/recommendations?

Thanks

È stato utile?

Soluzione

The "TryGet" approach is a little more explicit. With the null-returning approach, you have to document that the method returns null for such and such a reason, and this requires developers to read the documentation. As we all know, some people are allergic to reading documentation.

Another advantage of the "TryGet" approach is that you can use an enum rather than a bool, to give even more information to the caller about why and how the method failed (or succeeded).

Jeffrey Richter’s (CLR in C#) definition of an exception: When an action member cannot complete its task, the member should throw an exception. An exception means that an action member failed to complete the task it was supposed to perform as indicated by its name. My question is should I keep the GetValue method available for the client and raise an error when the data is unavailable or remove it and replace it with TryGetValue()?

Jeffrey Richter's definition is not helpful when you are determining the design of your API, because that includes determining what the tasks of each action member should be.

In your design, you are expecting the value to be unavailable as a matter of course; this means that it is not an exceptional situation for the value to be unavailable. I would therefore use only the TryGet... pattern.

But, truth be told, I would pursue a different approach altogether. Suppose somebody tries this approach:

while (!TryGetValue(key, out value)) {}

or:

SomeType value;
bool flag = false;
while (!flag)
{
    try
    {
        value = GetValue(key);
        flag = true;
     }
     catch {}
}

Your WCF service is going to get a lot of hits. It would probably be better to look into an asynchronous model, so the client is notified through a callback when the result is ready, rather than inviting the client to poll the service continually.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top