2013-04-18 12 views
7

SignalR में उपयोग करते हुए सार्वजनिक संपत्ति जैसे HubConnectionContext में परिभाषित किया गया है के रूप में एक चर का उपयोग कैसे करें: All.someMethodName(); जो शानदार है:एक विधि नाम गतिशील वस्तुओं

public dynamic All { get; set; } 

यह इसे पसंद कॉल करने के लिए उपयोगकर्ताओं को सक्षम बनाता है।

अब मैं अपने फ़ंक्शन में आने वाले पैरामीटर का उपयोग करके इसे कॉल करना चाहता हूं। मैं यह कैसे कर सकता हूँ?

में के रूप में: 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!) 
    } 
+1

आप इसे और अधिक स्पष्ट कर सकते हैं? –

+0

आपको प्रतिबिंब का उपयोग करने की आवश्यकता होगी। कुछ 'All.GetType()। GetMethod (पैरामीटर) .वॉव (सभी, नई वस्तु [] {}); '। –

+0

धन्यवाद जेप - यह कॉल को बहुत धीमा कर देगा ... अगर यही एकमात्र तरीका है तो मुझे चीजों को अलग-अलग करना पड़ सकता है! – Marcel

उत्तर

14

जब मैं सब मज़ा प्रतिबिंब जवाब प्यार करता हूँ, वहाँ एक एक का उपयोग कर क्लाइंट हब विधियों का आह्वान करने के लिए बहुत आसान और तेज़ तरीका विधि नाम के रूप में स्ट्रिंग।

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

'GetMethod'' गतिशील ' –

+0

के पीछे 'ExpandoObject' जैसा कुछ है, तो यह शून्य हो सकता है हां, यह सच है। मैं इसे अपने उत्तर में शामिल करूंगा। –

+0

GetType() क्लाइंटप्रॉक्सी देता है लेकिन अगला कथन 'GetMethod' एक शून्य देता है (विधि मौजूद नहीं है) ... लेकिन हम जानते हैं कि यह एक गतिशील वस्तु है (मैं इस विधि को जोड़ने की कोशिश कर रहा हूं!) – 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

क्या आप परीक्षण कर सकते हैं यदि '((क्लाइंटप्रॉक्सी) (क्लाइंट्स.एएल))। Invoc (methodToCall, msg) 'मेरे लिए काम करता है? –

+0

@JeppeStigNielsen: क्या आप [इस] (http://msdn.microsoft.com/library/microsoft.aspnet.signalr.hubs.clientproxy.invoke.aspx) के बारे में बात कर रहे हैं? –

+0

@ जेप जो काम करता है !! प्रतिभाशाली! - सुनिश्चित नहीं है कि मैं आपको जवाब कैसे दे सकता हूं! :) बहुत बहुत धन्यवाद! – Marcel

0

आप विधि को खोजने के लिए प्रतिबिंब का उपयोग कर सकते हैं। लेकिन यह केवल तभी काम करेगा यदि यह एक "वास्तविक" गैर-गतिशील विधि है जिसे सामान्य गैर-गतिशील तरीके से परिभाषित किया गया है, केवल dynamic कीवर्ड के पीछे छिपा हुआ है।

यदि फिर भी वस्तु All एक ExpandoObject या कुछ और System.Dynamic.DynamicObject, कुछ "विधि" हो सकता है कि केवल कार्यावधि में प्रकार के साथ जुड़े थे से पाने की तरह वास्तव में गतिशील है, और उस मामले में typeof(All).GetMethod कुछ भी नहीं मिलेगा ।

यह इलिया इवानोव था जिसने मूल रूप से John Willemse's answer पर टिप्पणी में इसे इंगित किया था। यह स्पष्ट हो गया कि वस्तु Microsoft.AspNet.SignalR.Hubs.ClientProxy उदाहरण है।

इसलिए, उस प्रकार के दस्तावेज़ से, समाधान है:

string methodToCall = XXX; 
string msg = YYY; 
((ClientProxy)(Clients.All)).Invoke(methodToCall, msg); 
संबंधित मुद्दे