7

在 SignalR 中,在 HubConnectionContext 中定义了公共属性,如下所示:

public dynamic All { get; set; }

这使用户可以这样称呼它:All.someMethodName(); 太棒了。

我现在想在我的函数中使用传入参数来调用它。我怎样才能做到这一点?

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

有没有办法做到这一点?

谢谢

编辑示例:

    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!)
    }
4

4 回答 4

15

虽然我喜欢所有有趣的反射答案,但有一种更简单、更快捷的方法可以使用字符串作为方法名称来调用客户端集线器方法。

Clients.All, Clients.Others, Clients.Caller, Clients.AllExcept(connectionIds), Clients.Group(groupName), Clients.OthersInGrouop(groupName), 和Clients.Client(connectionId)都是动态对象,但它们也都实现了IClientProxy接口。

您可以将这些动态对象中的任何一个转换为IClientProxy,然后调用Invoke(methodName, args...)

public void AcceptSignal(string methodToCall, string msg)
{

    IClientProxy proxy = Clients.All;
    proxy.Invoke(methodToCall, msg);
}
于 2013-04-18T18:40:01.353 回答
2

您可以使用反射来实现这一点:

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);
}
于 2013-04-18T10:03:38.247 回答
1
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();
}
于 2013-04-18T10:59:36.113 回答
0

您可以使用反射来找到方法。但这仅适用于以通常的非动态方式定义的“真实”非动态方法,仅隐藏在dynamic关键字后面。

但是,如果对象All是真正动态的,例如ExpandoObject从 派生的 an 或其他东西System.Dynamic.DynamicObject,则“方法”可能是仅在运行时与类型相关联的东西,在这种情况下typeof(All).GetMethod将找不到任何东西。

最初是 Ilya Ivanov 在对John Willemse 的回答的评论中指出了这一点。很明显,该对象是一个Microsoft.AspNet.SignalR.Hubs.ClientProxy实例。

因此,从该类型的文档中,解决方案是:

string methodToCall = XXX;
string msg = YYY;
((ClientProxy)(Clients.All)).Invoke(methodToCall, msg);
于 2013-04-18T19:58:26.523 回答