2012-07-09 2 views
2

내 응용 프로그램에서 WCF를 사용하여 웹 서비스를 호출합니다. 이 호출은 여러 가지 이유로 실패 할 수 있습니다 : 제한 시간 클라이언트의 WCF 오류 기록

  • 연결이
  • 을 잃은
    • 잘못 ...

    나는 이러한 모든 오류를 기록하고 싶다. try-catch에서 모든 호출을 래핑하는 대신 전체 응용 프로그램에서 모든 웹 서비스 호출에 대해 한 곳에서이 작업을 수행하려고합니다.

    아쉽게도 IClientMessageInspector가 시간 초과 및 연결 실패로 호출되지 않습니다. 모든 예외를 중앙에서 기록하는 데 사용할 수있는 WCF 확장 지점이 있습니까?

    WCF 추적과 같은 텍스트 오류를 ​​기록하고 싶습니다. 나는 기록 할 :

    • ServiceName은
    • methodName로
    • 기간
    • Exception.ToString()

    내가 해결에 열려입니다.

  • +0

    당신은 당신의 전화 중 하나의 코드 샘플 예제를 제공 할 수 있습니까? 현재 통화 당 서비스를 만들고, 호출하고, 처리하고 있습니까? –

    +0

    @ JTorres, 인스턴스 당 1-10 건으로 나오는 "작업 단위"당 한 번씩 서비스 프록시를 인스턴스화합니다. 이것은이 장소를 예외 처리기를 추가 할 때 다시 사용할 수 없음을 의미합니다. – usr

    +0

    나는 당신이 말하는 것을 이해하고 있다고 믿는다. (서비스 레퍼런스를 만들고, 1에서 10 개의 메소드를 호출하여 참조를 파괴한다.) 당신이하려고하는 것은 (1) 그것이 코드를보기 흉하게 보이게하고 (2) 그렇게하기 위해 많은 코딩을하기 때문에 실제로 코드에서 오류 처리를 작성하지 않고 이것들을 둘러싼 에러 핸들링을 추가하는 것입니다. 불행히도, 나는 네가 꽤 붙어 있다고 생각한다. 내가 생각할 수있는 "확장"솔루션에 가장 가까운 것은 PostSharp와 같은 AOP 유틸리티를 사용하고 호출을 적절한 부분으로 꾸미는 것입니다. @Trey Combs의 솔루션은 더 나은 디자인을 만들 것입니다. –

    답변

    1

    확장성에 대해 잘 모르지만 사용했던 해결 방법을 제공 할 수 있습니다. 기본적으로 우리는 모든 서비스 호출이 만들어지는 "프록시"를 만들었습니다. 아래는 프록시와 그 사용 예입니다.

    /// <summary> 
    /// Proxy for executing generic service methods 
    /// </summary> 
    public class ServiceProxy 
    { 
        /// <summary> 
        /// Execute service method and get return value 
        /// </summary> 
        /// <typeparam name="C">Type of service</typeparam> 
        /// <typeparam name="T">Type of return value</typeparam> 
        /// <param name="action">Delegate for implementing the service method</param> 
        /// <returns>Object of type T</returns> 
        public static T Execute<C, T>(Func<C, T> action) where C : class, ICommunicationObject, new() 
        { 
         C svc = null; 
    
         T result = default(T); 
    
         try 
         { 
          svc = new C(); 
    
          result = action.Invoke(svc); 
    
          svc.Close(); 
         } 
         catch (FaultException ex) 
         { 
          // Logging goes here 
          // Service Name: svc.GetType().Name 
          // Method Name: action.Method.Name 
          // Duration: You could note the time before/after the service call and calculate the difference 
          // Exception: ex.Reason.ToString() 
    
          if (svc != null) 
          { 
           svc.Abort(); 
          } 
    
          throw; 
         } 
         catch (Exception ex) 
         { 
          // Logging goes here 
    
          if (svc != null) 
          { 
           svc.Abort(); 
          } 
    
          throw; 
         } 
    
         return result; 
        } 
    } 
    

    그리고 그것의 사용의 예 :

    var result = ServiceProxy.Execute<MyServiceClient, MyReturnType> 
    (
        svc => svc.GetSomething(someId) 
    ); 
    
    +0

    이 솔루션을 사용할 수는 있지만 전체 응용 프로그램에서 약 100 건의 서비스 호출을 변경하는 것은 좋지 않습니다 ... 그리고 나는 이들 모두를 다시 테스트하고 싶지 않습니다. 나는 정말로 일종의 중심적인 해결책을 찾는다. – usr

    +1

    여러분이 시작한이 프로그램은 훌륭한 중심 솔루션이 될 것입니다. 이 제품은 상당히 강력한 유연성을 제공하지만, 개발의 여지가 상당히 떨어진 지금 구현하기 란 불가능합니다. 즉, 내가 알지 못하는 기적적인 처리자/행동을 제외하고는, 현재로서는 아무런 해결책도 고통스럽지 않을 것이라고 생각합니다. –

    관련 문제