2013-04-18 33 views
7

Trong SignalR có tài sản công cộng quy định tại các HubConnectionContext như vậy:Làm thế nào để sử dụng một biến như một tên phương pháp sử dụng đối tượng năng động

public dynamic All { get; set; } 

Điều này cho phép người dùng có thể gọi nó là thích: All.someMethodName(); đó là rực rỡ.

Tôi bây giờ muốn gọi điều này bằng cách sử dụng tham số đến trong hàm của tôi. Tôi có thể làm cái này như thế nào?

Như trong: All.<my variable as method name>();

Có cách nào để thực hiện việc này không?

Cảm ơn

EDIT dụ:

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

Bạn có thể làm cho nó rõ ràng hơn? –

+0

Bạn sẽ cần phải sử dụng sự phản chiếu. Một cái gì đó như 'All.GetType(). GetMethod (theParameter) .Invoke (Tất cả, đối tượng mới [] {});'. –

+0

Cảm ơn Jeppe - điều này sẽ làm chậm các cuộc gọi đến nhiều ... Nếu đó là cách duy nhất tôi có thể phải làm những việc khác đi! – Marcel

Trả lời

14

Trong khi tôi yêu tất cả sự phản ánh câu trả lời vui vẻ, có một cách đơn giản hơn và nhanh hơn để gọi các phương thức trung tâm khách hàng bằng cách sử dụng string làm tên phương thức.

Clients.All, Clients.Others, Clients.Caller, Clients.AllExcept(connectionIds), Clients.Group(groupName), Clients.OthersInGrouop(groupName), và Clients.Client(connectionId) là mọi đối tượng năng động, nhưng họ cũng tất cả thực hiện các giao diện IClientProxy.

Bạn có thể đúc bất kỳ của các đối tượng động để một IClientProxy, và sau đó gọi Invoke(methodName, args...):

public void AcceptSignal(string methodToCall, string msg) 
{ 

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

Bạn có thể dùng phản ánh để đạt được điều này:

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' có thể trả về null nếu có cái gì đó như' ExpandoObject' đằng sau 'dynamic' –

+0

Vâng, đó là sự thật. Tôi sẽ bao gồm điều đó trong câu trả lời của tôi. –

+0

GetType() trả về ClientProxy nhưng câu lệnh kế tiếp 'GetMethod' trả về giá trị rỗng (phương thức không tồn tại) ... Nhưng chúng ta biết rằng vì nó là đối tượng động (tôi đang cố thêm phương thức này!) – 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

Bạn có thể kiểm tra nếu '((ClientProxy) (Clients.All)). Gọi (methodToCall, msg)' công trình, cho tôi? –

+0

@JeppeStigNielsen: Bạn đang nói về [this] (http://msdn.microsoft.com/library/microsoft.aspnet.signalr.hubs.clientproxy.invoke.aspx)? –

+0

@ Jeppe WORKS !! Rực rỡ! - không chắc làm thế nào tôi có thể trao giải đáp cho bạn! :) Cảm ơn rất nhiều! – Marcel

0

Bạn có thể sử dụng phản ánh để tìm phương pháp. Nhưng điều này sẽ chỉ hoạt động nếu nó là một phương pháp phi năng động "thực" được định nghĩa theo cách không động, thông thường, chỉ ẩn đằng sau từ khóa dynamic.

Tuy nhiên, nếu đối tượng All là thật sự năng động, giống như một ExpandoObject hay cái gì khác phát sinh từ System.Dynamic.DynamicObject, các "phương pháp" có thể là một cái gì đó mà chỉ được kết hợp với loại tại thời gian chạy, và trong trường hợp đó typeof(All).GetMethod sẽ không tìm thấy bất cứ điều gì .

Đó là Ilya Ivanov, người đã chỉ ra điều này, trong một nhận xét cho John Willemse's answer. Nó trở nên rõ ràng rằng đối tượng là một cá thể Microsoft.AspNet.SignalR.Hubs.ClientProxy.

Do đó, từ tài liệu của loại hình đó, giải pháp là:

string methodToCall = XXX; 
string msg = YYY; 
((ClientProxy)(Clients.All)).Invoke(methodToCall, msg); 
Các vấn đề liên quan