2010-10-19 4 views
0

Est-ce que quelqu'un a un bon exemple de gestion commune des erreurs pour les appels de service? Je viens de commencer un nouveau projet et je vois beaucoup de code en double que je n'aime pas et que je voudrais me débarrasser. Je parviens à le faire dans plusieurs autres couches, mais dans la couche mandataire faisant les appels aux services, c'est un peu plus difficile. Le code est essentiellement structuré comme suit:Appel de service d'enveloppement pour la gestion et le suivi des erreurs courantes dans WCF

ResponseType MyProxyFunc(different, parameters) 
    { 
     var client = MyServiceClient(); 
     using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
     { 
      try 
      { 
      var response = client.MyRequest(different, parameters); 
       if (response.ErrorCode != Constants.OK) 
       { 
        ProxyCommon.ThrowError(besvarelseDS.Status[0].ErrorCode); 
       } 
      } 
      finally 
      { 
      ProxyCommon.CloseWcfClient(client); 
      } 
      return response; 
     } 
    } 

Le code ci-dessus est juste un échantillon, l'objet ProxyCommon est une classe statique avec différentes méthodes (ne devrait probablement pas être abstraite au lieu de statique, mais qui est une autre discussion). Alors, quelqu'un a-t-il une bonne suggestion sur la façon d'abstraire ce morceau de code? Je veux avoir l'utilisation, le try/catch et le if-statment dans une sorte de méthode abstraite, mais c'est difficile car MyServiceClient diffère, le nombre de paramètres diffère et la requête n'est pas la même.

EDIT: Un modèle que j'ai utilisé auparavant est d'utiliser une fonction générique Execute comme public T Execute<T>(Func<T> func). Mais je ne peux pas obtenir ce type de modèle pour fonctionner dans ce cas.

EDIT # 2: J'ai mis à jour le code mais je ne suis pas satisfait à 100%, plus comme 60-75%. Le problème avec le code ci-dessous est qu'il utilise les objets de service et ils ne seront pas identiques pour tous les services, mais cela fonctionnera pour les appels de service contre le service dans l'exemple avec une requête et un objet de réponse encapsulés. Mais je ne pense toujours pas que ce soit la solution au problème:

public IList<PGSA.Data.Cargo.PGSAReportCargo> GetPGSAReport(DateTime dateFrom, DateTime? dateTo) 
{ 
    var reportService = new ReportServiceClient(); 
    var request = new GetPGSAReportRequest() 
    { 
     SystemCode = Settings.SystemID, 
     FromDate = dateFrom, 
     ToDate = dateTo 
    }; 
    var response = Execute(reportService, reportService.GetPGSAReport, request); 
    return response.PGSAReport.ToList(); 
} 

public L Execute<T, K, L>(T client, Func<K, L> serviceFunc, K request) 
    where T : ICommunicationObject 
    where K : RequestBase 
    where L : ResponseBase 
{ 
    using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
    { 
     try 
     { 
      L response = serviceFunc(request); 
      if (response.ErrorCode != Constants.OK) 
      { 
       ProxyCommon.ThrowError(response.ErrorCode); 
      } 
      return response; 
     } 
     finally 
     { 
      ProxyCommon.CloseWcfClient(client); 
     } 
    } 
} 

EDIT # 3: Le ResponseBase et RequestBase dans EDIT # 2 sont des classes de base définies par le service.

Répondre

1

Votre approche semble bien me - je simplifier un peu comme suit:

public R Execute<T, R>(this T client, Func<R> serviceFunc) 
    where T : ICommunicationObject 
    where L : ResponseBase 
{ 
    using (Tracer functionTracer = new Tracer(Constants.TraceLog)) 
    { 
     try 
     { 
      R response = serviceFunc(); 
      if (response.ErrorCode != Constants.OK) 
      { 
       ProxyCommon.ThrowError(response.ErrorCode); 
      } 
      return response; 
     } 
     finally 
     { 
      ProxyCommon.CloseWcfClient(client); 
     } 
    } 
} 

et de l'utiliser

reportService.Execute(() => reportService.GetPGSAReport(request)); 

idée ici est d'éliminer la dépendance sur l'objet de la demande ne sont pas nécessaires.

+0

Votre réponse est une amélioration car elle permet des appels de fonction "vides". Cependant, ce n'est pas une solution à mon problème. J'ai fait une autre mise à jour pour clarifier que 'ResponseBase' et' RequestBase' sont des classes définies par le service, si vous travaillez avec plusieurs services, ces classes finiront dans des espaces de noms différents et ne pourront pas être utilisées de cette manière générale => one Fonction "Execute" par proxy de service essentiellement. –

+0

Vous obtenez la réponse depuis que vous l'avez essayé et je pense que ce sont les fermetures que vous pouvez obtenir :). –

Questions connexes