How to use a variable as a method name using dynamic objects

SignalR has a public property defined in the HubConnectionContext as such:

public dynamic All { get; set; } 

This allows users to call it the following: All.someMethodName(); which is brilliant.

Now I would like to call it using an input parameter in my function. How can i do this?

Like in: All.<my variable as method name>();

Is there any way to do this?

thanks

EDIT example:

  public void AcceptSignal(string methodToCall, string msg) { Clients.All.someMethod(msg); // THIS WORKS Clients.All.<methodToCall>(msg); // THIS DOES NOT WORK (But I would like it to!) } 
+7
source share
4 answers

While I like all the fun answers to thinking about, there is a much simpler and faster way to call client hub methods using a string as the name of the method.

Clients.All , Clients.Others , Clients.Caller , Clients.AllExcept(connectionIds) , Clients.Group(groupName) , Clients.OthersInGrouop(groupName) and Clients.Client(connectionId) are all dynamic objects, but they also implement the IClientProxy Interface .

You can apply any of these dynamic objects to IClientProxy and then call Invoke (methodName, args ...) :

 public void AcceptSignal(string methodToCall, string msg) { IClientProxy proxy = Clients.All; proxy.Invoke(methodToCall, msg); } 
+14
source

You can use reflection to achieve this:

 Type allType = All.GetType(); // GetType() may return null in relation to dynamics objects if (allType != null) { MethodInfo methodInfo = allType.GetMethod(methodToCall); methodInfo.Invoke(All, null); } 
+2
source
 public void AcceptSignal(String methodToCall, String msg) { var count=( from target in new[] { Clients.All } from memberInfo in ((Type)target.GetType()).GetMember(methodToCall) where MemberTypes.Method==memberInfo.MemberType let methodInfo=memberInfo as MethodInfo let paraInfos=methodInfo.GetParameters() where null!=paraInfos.FirstOrDefault(x => msg.GetType()==x.ParameterType) select methodInfo.Invoke(target, new object[] { msg }) ).Count(); } 
+1
source

You can use reflection to find a method. But this will only work if it is a “real” non-dynamic method, which is defined in the usual non-dynamic way, only hidden behind the dynamic keyword.

If, however, the All object is truly dynamic, such as an ExpandoObject or something else derived from System.Dynamic.DynamicObject , the “method” may be something that was associated only with the type at run time, in which case typeof(All).GetMethod will not find anything.

It was Ilya Ivanov, who initially pointed this out in a comment on John Willem's answer . It became apparent that the object is a Microsoft.AspNet.SignalR.Hubs.ClientProxy instance.

Therefore, from the documentation of this type, the solution is:

 string methodToCall = XXX; string msg = YYY; ((ClientProxy)(Clients.All)).Invoke(methodToCall, msg); 
0
source

All Articles