使用委托转换wcf服务返回对象

时间:2012-09-19 02:41:56

标签: .net vb.net wcf delegates

下面的函数接受任何wcf服务方法并调用它。

Private Function ServiceCall(ByVal functionToCall As ServiceDelegate(Of IEmpService)) As Object
    Dim channel As New ChannelFactory(Of IEmpService)(_endPoint)
    Dim serv As IEmpService
    Dim result As Object = Nothing
    Dim mostRecentExp As Exception = Nothing
    Dim noOfRetries As Integer = My.Settings.NoOfRetries
    Dim initialDelay As Integer = My.Settings.InitialDelayInMS

    serv = channel.CreateChannel()

    For i As Integer = 0 To noOfRetries

        Try
            result = functionToCall.Invoke(serv)
            mostRecentExp = Nothing
            Exit For
        Catch cte As ChannelTerminatedException
            mostRecentExp = cte

            Thread.Sleep(initialDelay * (i))
        Catch enf As EndpointNotFoundException
            mostRecentExp = enf
            Thread.Sleep(initialDelay * (i))
        Catch stb As ServerTooBusyException
            mostRecentExp = stb
            Thread.Sleep(initialDelay * (i))

        Catch vf As FaultException(Of ValidationFault)
            'no retry

        Catch exp As Exception 'any other exception 
            mostRecentExp = exp
            Thread.Sleep(initialDelay * (i))

        Finally
            If channel.State = CommunicationState.Faulted Then
                channel.Abort()
            Else
                channel.Close()
            End If
        End Try
    Next
    If mostRecentExp IsNot Nothing Then
        Throw New ServiceExceptions(String.Format("Call to method {0} failed", functionToCall.ToString()), mostRecentExp.InnerException)
    End If
    Return result
End Function

我根据我得到的异常类型确定是否需要重试,这一切都很好。 我面临的问题是result = functionToCall.Invoke(serv),其中结果是一个对象,它可以包含一个自定义错误对象,在这种情况下它不会是一个例外。 为了得到错误我可以做类似的事情:     If TypeOf result Is SaveAddressResponse Then ElseIf TypeOf result Is SaveDetailResponse Then End If 看起来很乱,所以想知道如果我可以使用委托从return对象中获取错误?

1 个答案:

答案 0 :(得分:0)

听起来你应该考虑让所有这些响应实现一个共同的界面,例如IFailureReporter允许您以统一的方式解决任何错误。然后你需要转换到那个接口(你可以无条件地做你的响应的所有实现该接口),并检查错误的方式。

编辑:如果这不可行,还有另外一种可能的方式,将每个类型的委托存储在字典中。我不清楚你想要的错误,或者它在每个响应对象中的表现方式......但是这样的事情会这样做,如果你知道响应对象的确切类型(不仅仅是它们兼容的类型)。这是C#代码,但类似的VB代码应该是可行的 - 我不太可能做对:

private static readonly Dictionary<Type, Func<object, string>>
     ErrorExtracters = new Dictionary<Type, Func<object, string>>
{
    { typeof(SaveAddressResponse), response => ((SaveAddressResponse) response).Error,
    { typeof(OtherResponse), response => ((OtherResponse) response).ErrorMessage,
    ...
};

然后:

Func<object, string> extractor;
if (ErrorExtractors.TryGetValue(result.GetType(), out extractor))
{
    string error = extractor(result);
    if (error != null)
    {
        ...
    }
}