Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用RealProxy包装多个WCF连接_Wcf_Expression_Realproxy - Fatal编程技术网

使用RealProxy包装多个WCF连接

使用RealProxy包装多个WCF连接,wcf,expression,realproxy,Wcf,Expression,Realproxy,我正在从事一个项目,在这个项目中,我们的服务器与几个暴露相同接口的服务器通信(如集群中)。我们使用循环选择将请求发送到哪个服务器。到目前为止,我们一直在使用Expression调用ClusterManager,但这会导致一些糟糕的代码。这也使得单元测试变得混乱,验证方法参数也有点困难。这似乎也会导致Moq的一些问题和随机的例外(不是本文的主题) 我目前调用了本文中记录的服务器和单元测试 关于要点: 我目前的做法如下: public interface IServerAdapter {

我正在从事一个项目,在这个项目中,我们的服务器与几个暴露相同接口的服务器通信(如集群中)。我们使用循环选择将请求发送到哪个服务器。到目前为止,我们一直在使用Expression调用ClusterManager,但这会导致一些糟糕的代码。这也使得单元测试变得混乱,验证方法参数也有点困难。这似乎也会导致Moq的一些问题和随机的例外(不是本文的主题)

我目前调用了本文中记录的服务器和单元测试

关于要点:

我目前的做法如下:

public interface IServerAdapter 
{
    void CallServer(Expression<Action<IServerExposingToClient>> methodToCall, out bool serverCalled);
}

private void DoSomething()
{
    MainViewModel.ServerAdapter.CallServer(server => server.SaveServerSettings(ServerSettings));
}
ServerProxy是一个RealProxy,我需要将此调用转换为ClusterManager以执行对服务器的实际调用。目前,ClusterManager具有与CallServer相同的签名,这对于现有实现来说有点多余。对于调用调用(IMessage)的翻译,我有两个想法

想法1 将IMethodCallMessage转换为lamda表达式(我还不知道该怎么做),并将其传递给ClusterManager。除了我不知道如何创建表达式,然后再次处理返回值的问题。某些方法返回值,而其他方法不返回值,因此这需要保留ClusterManager.CallServer的多个重载。我还需要创建IMessage以从Invoke返回

创意2 获取我当前用于调用服务器的WCF连接的TransparentProxy的RealProxy,并使用我得到的消息直接调用Invoke。在我的试用(使用集成测试)中,我似乎能够成功调用服务器,但通过ReturnMessage查看,没有返回值,并且当ServiceChannelProxy尝试获取消息数据时,Exception属性设置为ArithMetriceException。这可能是因为我在测试中出错,或者我不能在两个单独的代理上使用相同的LogicalCallContext(或其他内容)

关于如何处理这个问题有什么建议吗?我更喜欢想法2,因为它似乎是最简单的,并且希望产生的代码量最少。在一个类中实现IServerExposingToClient中的所有方法以调用正确的服务器不是我想做的事情


关于如何处理这个问题有什么建议吗

使用找到的信息,我已经能够解决这个问题。在下面的代码中,proxy是WCF服务通道的ICommunicationObject。看来效果不错

public override IMessage Invoke(IMessage msg)
{
    var methodCall = (IMethodCallMessage)msg;
    var proxy = FindNextProxy();
    try
    {
        MethodBase methodBase = methodCall.MethodBase;
        object[] args = methodCall.Args;
        object returnValue = methodBase.Invoke(proxy, args);
        return CreateReturnMessage(returnValue, methodCall);
    }
    catch (TargetInvocationException ex)
    {
        return CreateReturnMessage(ex.InnerException, methodCall);
    }
}
public override IMessage Invoke(IMessage msg)
{
    var methodCall = (IMethodCallMessage)msg;
    var proxy = FindNextProxy();
    try
    {
        MethodBase methodBase = methodCall.MethodBase;
        object[] args = methodCall.Args;
        object returnValue = methodBase.Invoke(proxy, args);
        return CreateReturnMessage(returnValue, methodCall);
    }
    catch (TargetInvocationException ex)
    {
        return CreateReturnMessage(ex.InnerException, methodCall);
    }
}