.NET Remoting с отражением - PullRequest
3 голосов
/ 17 мая 2011

Мне нужно динамически загрузить интерфейсную сборку, которую я использую при удаленном взаимодействии на стороне клиента. Как то так.

static void Main(string[] args)
{
  TcpClientChannel clientChannel = new TcpClientChannel();
  ChannelServices.RegisterChannel(clientChannel, false);

  Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
  Type iTheInterface = 
    interfaceAssembly.GetType("RemotingInterface.ITheService");

  RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
                                        "tcp://localhost:9090/Remotable.rem");
  object wellKnownObject = Activator.GetObject(iTheInterface, 
                                        "tcp://localhost:9090/Remotable.rem");
}

Только я не могу понять, как вызывать какие-либо методы, так как не могу привести Activator.GetObject. Как создать прокси-сервер ITheService, не зная интерфейса во время компиляции?

Ответы [ 4 ]

3 голосов
/ 23 мая 2011

Получил ответ от MSDN форумов .

static void Main(string[] args)
{
  TcpClientChannel clientChannel = new TcpClientChannel();
  ChannelServices.RegisterChannel(clientChannel, false);

  Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
  Type iTheInterface = interfaceAssembly.GetType("RemotingInterface.ITheService");

  RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
                                    "tcp://localhost:9090/Remotable.rem");
  object wellKnownObject = Activator.GetObject(iTheInterface, 
                                    "tcp://localhost:9090/Remotable.rem");

  MethodInfo m = iTheInterface.GetMethod("MethodName");
  m.Invoke(wellKnownObject, new object[] { "Argument"});
}
0 голосов
/ 26 марта 2012

Могу ли я получить информацию об интерфейсе с удаленного URL-адреса, например http://localhost:8080/xxx.rem?wsdl.

Как WebService, я могу получить информацию об интерфейсе из URL-адреса службы http://xXX.xx.xxx.xx/url.svc?wsdl,, скомпилировать сборку самостоятельно и вызвать методы через отражение.

0 голосов
/ 17 мая 2011

Сначала проверьте доступные методы / интерфейсы вашего объекта:

object wellKnownObject =
  Activator.GetObject(iTheInterface, "tcp://localhost:9090/Remotable.rem");

var objType = wellKnownObject.GetType();
var methods = objType.GetMethods();
var interfaces = objType.GetInterfaces();

Убедившись в том, что метод вы хотите вызвать,

  1. Рассмотрите возможность использования DLR и / или перенос динамического объекта в контейнер DynamicObject.
  2. Использование methods[i].Invoke для объекта.

Вот несколько примеров:

namespace ConsoleApplication1
{
  using System;

  class Program
  {

    static void Main()
    {
      //Using reflection:
      object obj = GetUnknownObject();
      var objType = obj.GetType();

      var knownInterface = objType.GetInterface("IA");
      var method = knownInterface.GetMethod("Print");
      method.Invoke(obj, new object[] { "Using reflection" });

      //Using DRL
      dynamic dObj = GetUnknownObject();
      dObj.Print("Using DLR");

      //Using a wrapper, so you the dirty dynamic code stays outside
      Marshal marshal = new Marshal(GetUnknownObject());
      marshal.Print("Using a wrapper");

    }

    static object GetUnknownObject()
    {
      return new A();
    }
  } //class Program

  class Marshal
  {
    readonly dynamic unknownObject;
    public Marshal(object unknownObject)
    {
      this.unknownObject = unknownObject;
    }

    public void Print(string text)
    {
      unknownObject.Print(text);
    }
  }

  #region Unknown Types
  interface IA
  {
    void Print(string text);
  }

  class A : IA
  {
    public void Print(string text)
    {
      Console.WriteLine(text);
      Console.ReadKey();
    }
  }
  #endregion Unknown Types
}
0 голосов
/ 17 мая 2011

Возвращенный объект реализует интерфейс, поэтому вы можете использовать отражение, чтобы получить его методы-члены и вызвать их.

Или, в C # 4, вы можете использовать dynamic:

dynamic wellKnownObject = Activator.GetObject(iTheInterface, 
    "tcp://localhost:9090/Remotable.rem");

wellKnownObject.SomeMethod(etc ..);
...