簡體   English   中英

C#以一般方式調用使用反射的方法

[英]C# Invoking a method using reflection in a generic manner

我有兩個過程(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; }
}

在A上調用Foo時,我想以相同的值在B上調用Foo。

這是A中的調用代碼:

public void Foo(SomeClass paramA, SomeOtherClass paramB)
{
    var args = new List<object> { paramA, paramB };
    m_Server.PushMessage(new PipeMessageArgs(MethodBase.GetCurrentMethod().Name, args));
}

這是B中的調用代碼:

void ClientOnReceiveMessage(NamedPipeConnection i_Connection, object i_Message)
{
    var pipeMessageArgs = i_Message as PipeMessageArgs;
    GetType().GetMethod(pipeMessageArgs.MethodName).Invoke(this, pipeMessageArgs.Args.ToArray());
}

但是如您所見,我必須為每個調用手動創建參數列表,因此,如果我忘記了一個參數或弄錯了順序,將無法正常工作。 鑒於我無法使用反射來獲取值,並且我不想使用分析器(性能是一個問題),使它更通用的最佳方法是什么?

編輯:由於太多原因,我無法使用WCF(實際上,我正在遠離WCF)。 我正在使用管道,即PipeStream。

Edit2:我想要的是一個不依賴於手動創建參數數組的解決方案。 可以自動為我創建此數組的東西。

我最終使用了RealProxy 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();
        }
    }

我使用i_MethodCall.InArgs來獲取參數,這就是問題所在。 還要注意HandleMethodCall如何使用管道推送消息,而不是實際調用請求的方法。 這意味着我的“ API”類實際上只是沒有實現的空方法(我可以隨時在其中添加更多實現,並在管道操作之前/之后調用該方法):

class Api : MarshalByRefObject, IApi
    {
        public void Foo(SomeClass paramA, SomeOtherClass paramB)
        {
        }

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

另外,作為RealProxy的要求。 該類必須繼承自MarshalByRefObject,這對我來說很好,因為它沒有其他功能。 在我鏈接的博客文章中了解有關它的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM