2016-09-14 80 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类,所以你不必亲手写它。