如果使用通用的System.action()调用,如何从WCF调用返回值?

时间:2013-03-27 18:24:02

标签: c# wcf

为了减少我们的团队在StartProcess方法中为来自单个方法的所有调用调用WCF实现的代码量。这一切都很好,但由于泛型方法的实际调用使用System.Action来调用,它永远不会返回一个值,因为我正在进行其中一个调用,我想发出请求/回复,我可以'得到那个回报值。

以下是处理WCF请求的Generic方法:

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 个答案:

答案 0 :(得分:2)

您可以使用Action<T>来允许回调将值返回给Func<T, TResult>调用者,而不是使用StartProcess作为回调参数。但是,这将要求所有回调都需要更改为返回值的函数。如果您只有一个需要返回回复的回调,可能不是一个快乐的想法。

另一种有点脏的方法可能是直接在CreateOnDemandDataDc回调函数中编写对当前活动的OperationContext的响应。查看OperationContext.Current.RequestContext.Reply及相关属性/方法。

答案 1 :(得分: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
  );
}