C#以通用方式调用使用反射的方法

C#以通用方式调用使用反射的方法,c#,reflection,named-pipes,C#,Reflection,Named Pipes,我有两个进程(A和B),都有一个方法Foo(SomeClass paramA,SomeOtherClass paramB)。 进程使用Windows管道(非WCF)进行通信,并可以发送和接收以下类型的消息: public class PipeMessageArgs { public PipeMessageArgs(string i_MethodName, List<object> i_Args) { MethodName = i_Method

我有两个进程(A和B),都有一个方法Foo(SomeClass paramA,SomeOtherClass paramB)。 进程使用Windows管道(非WCF)进行通信,并可以发送和接收以下类型的消息:

public class PipeMessageArgs
{
     public PipeMessageArgs(string i_MethodName, List<object> i_Args)
      {
          MethodName = i_MethodName;
          Args = i_Args;
      }

      public string MethodName { get; private set; }
      public List<object> Args { get; private set; }
}
但正如您所看到的,我必须为每个调用手动创建一个参数列表,因此如果我忘记了一个参数或顺序错误,事情将无法正常进行。鉴于我不能使用反射来获取值,并且我不想使用探查器(性能是个问题),那么让它更通用的最佳方法是什么

编辑:我不能使用WCF有太多的原因(实际上,我正在远离WCF)。我使用的是管道,即PipeStream

Edit2:我想要的是一个不依赖于手动创建参数数组的解决方案;可以为我自动创建此阵列的东西。

我最终使用了。RealProxy主要用于远程处理,但允许您为类创建代理。然后,您可以在每个方法调用(以及属性调用)之前添加功能。我使用这个非常好的工具来实现它

这是我的代理:

public class InvokingProxy : RealProxy
    {
        private readonly INamedPipe _namedPipe;

        InvokingProxy(object i_Target, INamedPipe i_NamedPipe) : base(i_Target.GetType())
        {
            _namedPipe = i_NamedPipe;
        }

        public override IMessage Invoke(IMessage i_Msg)
        {
            var methodCall = i_Msg as IMethodCallMessage;

            if (methodCall != null)
            {
                return HandleMethodCall(methodCall);
            }

            return null;
        }

        IMessage HandleMethodCall(IMethodCallMessage i_MethodCall)
        {
            _namedPipe.PushMessage(new PipeMessageArgs(i_MethodCall.MethodName, i_MethodCall.InArgs));
            return new ReturnMessage(null, null, 0, i_MethodCall.LogicalCallContext, i_MethodCall);
        }

        public static T Wrap<T>(T i_Target, INamedPipe i_NamedPipe) where T : MarshalByRefObject
        {
            return (T)new InvokingProxy(i_Target, i_NamedPipe).GetTransparentProxy();
        }
    }

另外,作为RealProxy的一个要求。该类必须从MarshalByRefObject继承,这对我来说很好,因为它没有其他功能。在我链接的博客文章中阅读更多关于它的信息。

hmm。你可以使用字典而不是列表,把参数名放在键中?但实际上,我希望让它不那么通用,并创建一些强类型的通信方法。不确定您可以更改多少?是的,我知道我可以克服排序问题,我真正想要的是更通用的东西-可以节省我手动声明值集合的东西。您可以使用postsharp之类的后期编译器为您自动生成列表方法。但您只是保存typing或更改所有方法以接受单个参数列表作为参数。那么你可以不加更改地发送这个
void ClientOnReceiveMessage(NamedPipeConnection i_Connection, object i_Message)
{
    var pipeMessageArgs = i_Message as PipeMessageArgs;
    GetType().GetMethod(pipeMessageArgs.MethodName).Invoke(this, pipeMessageArgs.Args.ToArray());
}
public class InvokingProxy : RealProxy
    {
        private readonly INamedPipe _namedPipe;

        InvokingProxy(object i_Target, INamedPipe i_NamedPipe) : base(i_Target.GetType())
        {
            _namedPipe = i_NamedPipe;
        }

        public override IMessage Invoke(IMessage i_Msg)
        {
            var methodCall = i_Msg as IMethodCallMessage;

            if (methodCall != null)
            {
                return HandleMethodCall(methodCall);
            }

            return null;
        }

        IMessage HandleMethodCall(IMethodCallMessage i_MethodCall)
        {
            _namedPipe.PushMessage(new PipeMessageArgs(i_MethodCall.MethodName, i_MethodCall.InArgs));
            return new ReturnMessage(null, null, 0, i_MethodCall.LogicalCallContext, i_MethodCall);
        }

        public static T Wrap<T>(T i_Target, INamedPipe i_NamedPipe) where T : MarshalByRefObject
        {
            return (T)new InvokingProxy(i_Target, i_NamedPipe).GetTransparentProxy();
        }
    }
class Api : MarshalByRefObject, IApi
    {
        public void Foo(SomeClass paramA, SomeOtherClass paramB)
        {
        }

        public void Bar(SomeClassX paramA, SomeOtherClassY paramB)
        {
        }
    }
}