【问题标题】:Dynamically executing delegates动态执行委托
【发布时间】:2012-11-19 16:03:35
【问题描述】:

我有一个基本上是消息处理程序的类,它接受请求,找到该消息类型的处理器,创建适当的响应并返回它。为此,我有 如下创建了一个委托public delegate Rs ProcessRequest<Rq,Rs>(Rq request);,然后在我的类中,创建了许多受支持的消息及其处理方法。问题是主进程方法应该弄清楚使用哪个进程方法找不到使用GetMethod()方法的方法。

这是整个代码,如果你能告诉我如何动态选择合适的方法然后执行它,那就是我要找的。​​p>

public delegate Rs ProcessRequest<in Rq, out Rs>(Rq request) where Rq : API.Request where Rs : API.Response;

public class WebSocketServer
{
    private WebSocketMessageHandler messageHander;

    // Incoming message handlers
    public ProcessRequest<InitUDPConnectionRq, InitUDPConnectionRs> ProcessInitUDPConnection;
    public ProcessRequest<ListenHandshakeRq, ListenHandshakeRs> ProcessListenHandshake;
    public ProcessRequest<PresenceChangeRq, PresenceChangeRs> ProcessPresenceChange;
    public ProcessRequest<ChatMessageRq, ChatMessageRs> ProcessChatMessage;
    public ProcessRequest<RDPRequestResponseRq, RDPRequestResponseRs> ProcessRDPRequestResponse;
    public ProcessRequest<RDPIncomingRequestRq, RDPIncomingRequestRs> ProcessRDPIncomingRequest;

    public WebSocketServer(WebSocketMessageHandler handler)
    {
        this.messageHander = handler;
    }

    public void processRequest(API.Request request)
    {
        String resquestType = request.GetType().Name;
        String processorName = resquestType.Substring(0, resquestType.Length - 2);
        API.Response response = null;
        // Do we have a process method for this processor
        MethodInfo methodInfo = this.GetType().GetMethod("Process" + processorName);
        if (methodInfo != null)
        {
             // Execute the method via Invoke...., but code never gets here
        }
        else
        {
            logger.Warn("Failed to find a processor for " + processorName);
            response = new ErrorRs(request.id, "Failed to find a processor for " + processorName);
        }
        sendResponse(response, request);
    }
}

现在我将这些字段分配给方法,我只是无法动态执行它们。

// Link into the hooks so we can receive requests
_appContext.ConnectionManager.Connection.webSocketServer.ProcessInitUDPConnection = ProcessInitUDPConnection;
_appContext.ConnectionManager.Connection.webSocketServer.ProcessListenHandshake = ProcessListenHandshake;
_appContext.ConnectionManager.Connection.webSocketServer.ProcessPresenceChange = ProcessPresenceChange;
_appContext.ConnectionManager.Connection.webSocketServer.ProcessChatMessage = ProcessChatMessage;

// 1 method as an example
private PresenceChangeRs ProcessPresenceChange(PresenceChangeRq request)
{
    _appContext.RosterManager.presenceChange(request.user, request.presence);
    return new PresenceChangeRs();
}

【问题讨论】:

  • 为什么不使用显式的Dictionary&lt;string, ProcessRequest&lt;...&gt;&gt; 而不是反射呢?应该更容易判断出了什么问题。
  • 您不应该使用this.GetType().GetField("Process" + processorName); 而不是GetMethod吗?
  • 很公平,但是在我从字典中检索到它之后,我将如何动态执行它,您能否给我看一些代码?
  • Chris:我试过了,我把它弄出来了,问题是,我该如何执行它?我尝试了 InvokeMember 没有成功,也许我只是不知道如何
  • 关于GetField()Delegate process = (Delegate)this.GetType().GetField("Process" + requestType).GetValue(this); process.DynamicInvoke(.....

标签: c# dynamic reflection delegates


【解决方案1】:

这里是Dictionary 用法的一些示例代码。对我来说,自定义类型太多了,无法确保它完全编译并经过测试,但应该能让你走上正轨。

public class WebSocketServer
{
    private WebSocketMessageHandler messageHander;

    // Incoming message handlers
    private Dictionary<string, System.Delegate> ProcessHandlers = new Dictionary<string, System.Delegate>();

    public void RegisterProcessHandler(string name, System.Delegate handler)
    {
        ProcessHandlers.Add(name, handler);
    }

    public void processRequest(API.Request request)
    {
        String resquestType = request.GetType().Name;
        String processorName = resquestType.Substring(0, resquestType.Length - 2);
        API.Response response = null;

        string processorName = "Process" + processorName;

        if (ProcessHandlers.ContainsKey(processorName))
        {
            System.Delegate myDelegate = ProcessHandlers[processorName]; 
            response = (API.Response)myDelegate.DynamicInvoke(request);
        }
        else
        {
            logger.Warn("Failed to find a processor for " + processorName);
            response = new ErrorRs(request.id, "Failed to find a processor for " + processorName);
        }

        sendResponse(response, request);
    }
}

注册:

var webSocketServer = _appContext.ConnectionManager.Connection.webSocketServer;
webSocketServer.RegisterProcessHandler("InitUDPConnection", ProcessInitUDPConnection);
webSocketServer.RegisterProcessHandler("ListenHandshake", ProcessListenHandshake);

【讨论】:

  • 这完全正确,谢谢克里斯,我只剩下一件事要做,那就是将我的方法转换为 RegisterProcessHandler 的 (ProcessRequest)processMethod。太棒了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
相关资源
最近更新 更多