Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically executing delegates

I have a class which is basically a message handler, it accepts requests, finds a processor for that message type, creates an appropriate response and returns it. To this end, I have created a delegate as follows public delegate Rs ProcessRequest<Rq,Rs>(Rq request); and then inside my class, created a number of supported messages and their process methods. The problem is the main process method which should figure out which process method to use can't find the method using the GetMethod() method.

Here is the whole code, if you could tell me how to dynamically select the appropriate method and then execute it, thats pretty much what I am looking for.

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);
    }
}

Now I assign those fields to methods as I go, I just can't dynamically execute them.

// 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();
}
like image 971
rendezz Avatar asked Nov 13 '22 17:11

rendezz


1 Answers

Here's some sample code for the Dictionary usage. Bit too many custom types for me to make sure it compiles fully and tested, but should get you on the right track.

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);
    }
}

Registration:

var webSocketServer = _appContext.ConnectionManager.Connection.webSocketServer;
webSocketServer.RegisterProcessHandler("InitUDPConnection", ProcessInitUDPConnection);
webSocketServer.RegisterProcessHandler("ListenHandshake", ProcessListenHandshake);
like image 110
Chris Sinclair Avatar answered Nov 15 '22 12:11

Chris Sinclair