2013-03-27 64 views
0

爲了減少代碼量,我們團隊使用StartProcess方法爲來自單個方法的所有調用調用WCF實現。這一切都很好,但由於來自泛型方法的實際調用使用System.Action來調用,它永遠不會返回值,並且因爲我正在進行的一個調用我想提出請求/答覆,所以我可以'噸得到那個回報價值。如果您使用泛型System.action()調用,如何從WCF調用返回值?

這裏是處理WCF請求的一般方法:

public static ProcessResultDC StartProcess<T>(T setupData, string processName, Action<T> action, string exteriorAccountNumber, string companyCode) where T : IAmValidatable, IHaveAProcessGuid { 

    var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted }; 
    // Do some authentication stuff here 

    try { 

     action(setupData); // <-- This returns void, but I would like to return a string to the client 

    } catch (Exception exc) { 
     result.Status = ProcessStatusEnum.Error; 
     result.Messages.Add(exc.Message); 
    } 
    return result; 
} 

這裏是客戶端調用:

var createOnDemandDataDc = new CreateOnDemandDataDc { RawData = punchRawData }; 
var result = TimeForceProcessHelper.StartProcess(createOnDemandDataDc, "Create On Demand Data", x => new CreateOnDemandDataProxy().CreateOnDemandData(createOnDemandDataDc), "NA", companyCode); 

結果變量無法瞭解從操作的字符串的方法調用,即使我的createOnDemandDataDc實現返回一個字符串。

有沒有更好的方法來做到這一點?或者我可以簡單地做一些Action()調用以獲得返回字符串嗎?

回答

2

而不是使用Action<T>作爲回調參數,您可以使用Func<T, TResult>來允許回調將值返回給StartProcess調用方。但是,這將需要您所有的回調函數都需要更改爲返回值的函數。如果你只有一個需要返回回覆的回調,可能不是一個快樂的想法。

另一個有點髒的方法可能是直接在CreateOnDemandDataDc回調函數中將響應寫入當前活動的OperationContext。看看OperationContext.Current.RequestContext.Reply和相關的屬性/方法。

+1

這太好了,我接受了你的建議,想出了一些中間的東西。我重構了StartProcess代碼,現在有另一種方法,StartProcessWithReturn實現您的建議,使用Func 。很棒!謝謝您的幫助。 – 2013-03-27 19:16:03

1

這也是我如何做AOP的。您需要兩種方法的各個方面 - 一個用於Action和一個用於Func

如果你寫了一個Func第一:

public static ProcessResultDC StartProcess<T, TResult>(
    T setupData, 
    string processName, 
    Func<T, TResult> fn, 
    string exteriorAccountNumber, 
    string companyCode 
) 
    where T : IAmValidatable, IHaveAProcessGuid 
{ 
    var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted }; 

    // Do some authentication stuff here 

    try 
    { 
    result.Result = fn(setupData); 
    } 
    catch (Exception exc) 
    { 
    result.Status = ProcessStatusEnum.Error; 
    result.Messages.Add(exc.Message); 
    } 

    return result; 
} 

然後,你可以寫一個Action使用Func實施:

public static ProcessResultDC StartProcess<T>(
    T setupData, 
    string processName, 
    Action<T> fn, 
    string exteriorAccountNumber, 
    string companyCode 
) 
    where T : IAmValidatable, IHaveAProcessGuid 
{ 
    return StartProcess(
    setupData, 
    processName, 
    t => { fn(t); return 0; }, 
    exteriorAccountNumber, 
    companyCode 
); 
} 
+0

謝謝尼古拉斯,非常好!我會實施這個設計,謝謝。 – 2013-03-27 19:19:42

+0

@MarkKadlec不客氣:) – 2013-03-27 19:22:47