2016-09-14 77 views
0

我正在開發一個項目,該項目允許客戶端針對其特定實例在服務器上調用遠程函數。基本上,當客戶端連接它時,它將獲得它自己的共享類的實例,然後客戶端將使用方法返回類型的名稱和參數+它們的預期類型來調用服務器。處理多重委託類型的一種通用方法

我正在做的方式是創建一個Prototypes類,並在其內部創建Delegates以表示Server內共享類內的Method原型。

  • Sub問題:最好的方法是什麼?我使用委託,但我不是一個有效的原型的雙重聲明的粉絲。一個接口是關於我想要的,但我可以找到創建它的一個實例的好方法,因爲我不確定Prototype類將包含什麼。

我會處理這一切的方式是當客戶端連接到服務器,客戶端將遍歷原型類,並得到所有的字段,它就會嘗試所有的領域裏面鏈接到一個通用的方法處理任何被調用的函數,然後該函數將得到它的聲明返回類型&參數信息等,然後將其發送到服務器。

我首先想到的是使用

params object[] param 

然而Delegate.CreateDelegate錯誤出在運行時,如果我說給它:

public delegate string TestDelegate(string s1, string s2, string[] s3); 

public TestDelegate Test; 

但是,如果我創建方法的多個重載所有代表正在鏈接回它工作精美ex:

public T handleFunc<T>(object param) 
    { 
     Console.WriteLine(param as string); 
     return default(T); 
    } 

    public T handleFunc<T>(object param, object param2) 
    { 
     Console.WriteLine(param as string); 
     return default(T); 
    } 

    public T handleFunc<T>(object param, object param2, object param3) 
    { 
     Console.WriteLine((param3 as string[])[0]); 
     return default(T); 
    } 

這是我的curre NT代碼來代表鏈接到handleFunc方法:

private void ValidatePrototypes() 
    { 
     var fields = typeof(Prototypes).GetFields(); 
     foreach (FieldInfo field in fields) 
     { 
      MethodInfo thisfield = field.FieldType.GetMethods()[0]; 

      ParameterInfo[] pi = thisfield.GetParameters(); 

      var handle = typeof(Client).GetMethod("handleFunc", Array.ConvertAll(pi, s => s.ParameterType)); 

      var lambda = handle.MakeGenericMethod(thisfield.ReturnType); 

      Delegate del = Delegate.CreateDelegate(field.FieldType, this, lambda); 

      field.SetValue(Functions, del); 
     } 
     Console.WriteLine(Functions.Test("", "", new[] { "Hello" })); 
    } 

我需要有效地對任何可能代表(或任何最好的變體)的一種方法能夠鏈接並能夠從那裏處理數據。

我很感激任何迴應。

+0

我覺得所有這些已經在WCF中完成了 –

回答

0

我認爲這是可以不用在運行時創建的代表來完成:

public interface IService { 
    string Foo(int x); 
} 
public class ServerClass : IService { 
    public string Foo(int x) { 
     return x.ToString(); 
    } 
} 

public class ClientStub : IService { 
    protected ITarget target; 
    public ClientStub(ITarget target) { 
     this.target = target; 
    } 
    public string Foo(int i) { 
     return (string)target.Invoke(nameof(Foo), i); 
    } 
} 

public interface ITarget { 
    object Invoke(string methodName, params object[] args); 
} 

public class RemoteTarget : ITarget { 
    public object Invoke(string methodName, params object[] args) { 
     // send params over network and return response 
    } 
} 

... 

new ClientStub(new RemoteTarget()).Foo(); 

用你的方法對此擁有一個沒有任何好處。他們通常在框架中做的事情是他們在運行時使用反射發射來實現ClientStub類,所以你不必親手寫它。