Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带反射的.NET远程处理_C#_.net_Reflection_.net Remoting_Activator - Fatal编程技术网

C# 带反射的.NET远程处理

C# 带反射的.NET远程处理,c#,.net,reflection,.net-remoting,activator,C#,.net,Reflection,.net Remoting,Activator,我需要动态加载在客户端远程处理上使用的接口程序集。像这样的 static void Main(string[] args) { TcpClientChannel clientChannel = new TcpClientChannel(); ChannelServices.RegisterChannel(clientChannel, false); Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.d

我需要动态加载在客户端远程处理上使用的接口程序集。像这样的

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的代理?

返回的对象实现接口,因此您可以使用反射获取其成员方法并调用它们

或者,在C#4中,您可以使用
dynamic

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

wellKnownObject.SomeMethod(etc ..);

首先,检查对象的可用方法/接口:

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

var objType = wellKnownObject.GetType();
var methods = objType.GetMethods();
var interfaces = objType.GetInterfaces();
确定要调用的方法后

  • 考虑在DynamicObject容器中使用和/或包装动态对象
  • 在对象上使用
  • 以下是一些例子:

    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
    }
    
    我从他那里得到了答案


    我可以从远程URL获取接口信息吗


    作为WebService,我可以从服务url获取接口信息,自己编写程序集代码,并通过反射调用方法。

    Hi Ben。谢谢你的回复。动态方法调用抛出RuntimeBinderException“System.MarshallByRefObject”不包含“SomeMethod”的定义。此外,我知道如何获取接口的方法,但不知道如何从wellKnownObject获取它们。
    SomeMethod
    是一个方法的示例名称。将其替换为您知道的界面中的方法。您能展示一个反射的示例吗?对象的类型为MarshalByRefObject。我不太确定如何将其映射到界面。@Shimmy,谢谢您的更新。不幸的是,你的例子都不起作用。请记住,我正在使用动态程序集加载和.NET远程处理。我甚至不知道服务器正在实例化的具体类,因此无法调用
    newa()
    。我必须使用
    Activator.GetObject
    ,但是我得到的对象类型是
    MarshalByRefObject
    ,它没有实现任何接口。如果调用
    objType.GetInterfaces
    ,则返回一个空数组。如果我以传统方式执行此操作并静态引用DLL,那么我可以调用
    IA knownInterface=(IA)Activator.GetObject(…)
    @Rubio,1)在我的示例中,
    新的A()
    是您的
    Activator.GetObject
    ,它是,共同点是,只有在运行时将变量类型设置为具体值时,才知道变量类型2)如何确保要查找的方法存在于该远程类中?3) 让我问你一个问题,你是用反射还是?@Shimmy,我明白了。2) 我不能。3) 是的。在我的示例代码
    knownInterface
    中,如果我像您那样获得它,它将为空。然而,如果我像在我的原始样本中那样得到它,它就会工作。所以从技术上讲,你的反射方法是正确的,我只是需要以不同的方式来获得界面。我仍然无法让DLR或包装器方法工作。我明白了。那很有趣。非常感谢。顺便说一句,如果您自己的答案回答了这个问题,请将其标记为答案。您是否考虑过使用WCF而不是远程处理?为了支持WCF,远程处理已被弃用。@John,我痛苦地意识到远程处理已被弃用。不幸的是,由于现有的客户端代码,我无法切换到WCF而不会对其他人的代码造成破坏。有一天…这篇文章是关于.NET远程处理的。如果你正在处理web服务,请使用Google“dynamic WCF”。如果你要将程序集加载到当前AppDomain中,并且你知道类型名,为什么不添加
    RemotingInterface.dll
    作为对项目的引用,这样你就可以像
    ITheInterface WellKnownoObject=(ITheInterface)Activator.GetObject(…)那样强制转换,然后直接执行该方法?如果您希望对动态加载的程序集进行沙箱处理,那么这并不能做到这一点。
    
    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"});
    }