2013-04-18 13 views
7

In SignalR mit dort verwenden, öffentliches Eigentum im HubConnectionContext als solche definiert ist:Wie eine Variable als Methodennamen dynamische Objekte

public dynamic All { get; set; } 

Dieser Benutzer es nennen ermöglicht mag: All.someMethodName(); die brillant.

Ich möchte dies jetzt mit einem eingehenden Parameter in meiner Funktion aufrufen. Wie kann ich das machen?

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

Gibt es eine Möglichkeit, dies zu tun?

Dank

EDIT Beispiel:

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!) 
    } 
+1

Können Sie es klarer machen? –

+0

Sie müssten Reflexion verwenden. So etwas wie 'All.GetType(). GetMethod (theParameter) .Invoke (Alle, neues Objekt [] {});'. –

+0

Danke Jeppe - das würde die Anrufe zu sehr verlangsamen ... Wenn das der einzige Weg ist, muss ich die Dinge vielleicht anders machen! – Marcel

Antwort

14

Während ich alle Spaß Reflexion Antworten lieben, gibt es eine ist viel einfacher und schneller Weg, Client-Hub-Methoden mit einem string als Methode Name.

Clients.All, Clients.Others, Clients.Caller, Clients.AllExcept(connectionIds), Clients.Group(groupName), Clients.OthersInGrouop(groupName) und Clients.Client(connectionId) sind alle dynamischen Objekte, aber sie alle auch die IClientProxy-Schnittstelle implementieren.

Sie können zu einem IClientProxy jeder dieser dynamischen Objekte werfen, und dann Invoke(methodName, args...) nennen:

public void AcceptSignal(string methodToCall, string msg) 
{ 

    IClientProxy proxy = Clients.All; 
    proxy.Invoke(methodToCall, msg); 
} 
2

Sie Reflexion dies zu erreichen, verwenden können:

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

'GetMethod' kann null zurückgeben, wenn etwas wie' ExpandoObject' hinter 'dynamic' steht. –

+0

Ja, das stimmt. Ich werde das in meine Antwort aufnehmen. –

+0

Der GetType() gibt einen ClientProxy zurück, aber die nächste Anweisung 'GetMethod' gibt eine Null zurück (die Methode existiert nicht) ... Aber wir wissen das, weil es ein dynamisches Objekt ist (Ich versuche diese Methode hinzuzufügen!) – Marcel

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(); 
} 
+0

Können Sie testen, ob '((ClientProxy) (Clients.All)). Invoke (methodToCall, msg)' funktioniert, für mich? –

+0

@JeppeStigNielsen: Sprichst du über [diese] (http://msdn.microsoft.com/library/microsoft.aspnet.signalr.hubs.clientproxy.invoke.aspx)? –

+0

@ Jeppe, das funktioniert !! Brillant! - nicht sicher, wie ich Ihnen die Antwort geben kann! :) Vielen Dank! – Marcel

0

Sie Reflektion verwenden können, um die Methode zu finden. Dies funktioniert jedoch nur, wenn es sich um eine "echte" nicht-dynamische Methode handelt, die auf die übliche nicht-dynamische Art und Weise definiert ist und nur hinter dem Schlüsselwort dynamic versteckt ist.

Wenn jedoch das Objekt All ist wirklich dynamisch, wie ein ExpandoObject oder etwas anderes aus System.Dynamic.DynamicObject abzuleiten, die „Methode“ etwas sein könnte, die nur mit dem Typ zur Laufzeit verbunden waren, und in diesem Fall typeof(All).GetMethod wird nichts finden .

Es war Ilya Ivanov, der ursprünglich darauf hinwies, in einem Kommentar zu John Willemse's answer. Es wurde offensichtlich, dass das Objekt eine Microsoft.AspNet.SignalR.Hubs.ClientProxy Instanz ist.

Daher ist aus der Dokumentation dieser Art, die Lösung ist:

string methodToCall = XXX; 
string msg = YYY; 
((ClientProxy)(Clients.All)).Invoke(methodToCall, msg); 
Verwandte Themen