2009-12-08 13 views
3

J'écris un service Web qui est un wrapper pour le service Web d'un fournisseur, et qui contient une série assez détaillée d'instructions catch pour un appel à des méthodes de service Web de fournisseur. J'ai deux ou trois types d'exceptions que je gère (System.Web.Services.Protocols.SoapException, System.ApplicationException, System.Exception ...)Traitement d'erreurs courantes C#

Je viens de réaliser que la plupart des erreurs sont les mêmes entre leur deux méthode Create et leur méthode Update.

Existe-t-il un moyen intelligent de partager les mêmes gestionnaires d'erreurs sur plusieurs méthodes? J'ai commencé à écrire juste une méthode commune, mais j'ai ensuite réalisé que je devais écrire au moins une méthode commune pour chaque type d'exception que je gère. Ce serait génial si je pouvais gérer chacun d'entre eux de la même manière.

Ceci est un service Web avec une interface établie. Juste en pensant à haute voix que j'écris ceci, je suppose que je pourrais mettre le moins de code possible dans les méthodes web, alors ils pourraient appeler une méthode partagée? Je veux juste m'assurer que je ne manque pas un truc évident.

Merci, Neal

Répondre

10

Vous pouvez créer une fonction qui prend un délégué puis appeler avec une expression lambda (C# 3) ou méthode anonyme. La fonction peut invoquer le passé dans Delegate dans un bloc try et gérer les exceptions.

private T CallWebService<T>(Func<T> function) 
{ 
    try 
    { 
     return function(); 
    } 
    catch (SoapException e) 
    { 
     // handle SoapException 
    } 
    catch (ApplicationException e) 
    { 
     // handle ApplicationException 
    } 
    // catch and handle other exceptions  
} 

public ReturnType CallCreate(ParamType param) 
{ 
    return CallWebService(() => WebService.InvokeCreate(param)); 
} 

public ReturnType CallUpdate(ParamType param) 
{ 
    return CallWebService(() => WebService.InvokeUpdate(param)); 
} 

Si les méthodes individuelles ont besoin de leurs propres exceptions spécifiques traitées, cela pourrait être ajouté aux méthodes CallCreate et CallUpdate.

L'exemple ci-dessus utilise des expressions lambda. L'équivalent de CallCreate en utilisant des méthodes anonymes est:

public ReturnType CallCreate(ParamType param) 
{ 
    return CallWebService<ReturnType>(delegate() 
    { 
     return WebService.InvokeCreate(param) 
    }); 
} 
+1

+1 - C'est la voie à suivre. – ChaosPandion

1

Vous pouvez utiliser l'approche délégué de Phil Ross, ou bien, vous pouvez créer une IWebMethodInvoker qui implémente une méthode Invoke():

interface IWebMethodInvoker 
{ 
    void Invoke(); 
} 

Ensuite, vous implémentez cette interface dans une classe pour chaque méthode Web appel:

class CreateInvoker : IWebMethodInvoker 
{ 
    public SomeDataType Data {get; set;} 
    public SomeOtherType Results {get; set;} 

    public void Invoke() 
    { 
     Results = YourWebServiceMethod(Data); 
    } 
} 

Ensuite, vous créez une méthode qui prend une instance de cette interface, invoque et fait la gestion des erreurs:

public void ExecuteWebServiceCall(IWebMethodInvoker invoker) 
{ 
    try 
    { 
     invoker.Invoke(); 
    } 
    catch (ExceptionType1 e) 
    { 
     // Handle Exception Type 1 
    } 
    catch (ExceptionType2 e) 
    { 
     // Handle Exception Type 2 
    } // etc 
} 

Ensuite, tout ce que vous devez appeler le service Web est la suivante:

var createInvoker = new CreateInvoker() { Data = someStuff }; 
ExecuteWebServiceCall(createInvoker); 
var results = createInvoker.Results; 

Cela pourrait être un peu plus taper que l'approche des délégués mais peut-être moins déroutant pour moins développeurs expérimentés.

+0

Je ne suis pas d'accord, cela le rend plus compliqué. – ChaosPandion

1

Y a-t-il une réelle valeur à gérer explicitement les différents types d'exceptions? c'est-à-dire qu'il existe un cas d'utilisation valide que vous devez gérer SoapException à partir d'une exception ApplicationException. La brume de l'époque n'y est pas.

Si vous pensez toujours qu'il existe une valeur, je suggère d'utiliser le bloc d'application ExceptionHandling du Enterprise Library. L'utilisation de EnterpriseLibrary dans ce type de scénario est plus propre et meilleure à mon avis que de pepper votre code avec de nombreux blocs catch.

+0

Bon point, avec Sql Exception vous obtenez plus d'informations, mais avec SoapException - Je n'ai rien vu d'utile là-bas je suppose. – NealWalters