【问题标题】:Get Namespace, classname from a dll in C# 2.0从 C# 2.0 中的 dll 获取命名空间、类名
【发布时间】:2010-12-08 06:54:18
【问题描述】:

我将动态获取 dll。我需要加载 dll 并获取命名空间、类名来调用方法(方法名称是静态的,它始终是“OnStart()”)。 基本上我需要通过加载dll来运行一个方法。有人可以帮忙吗!!!。

【问题讨论】:

    标签: c# reflection namespaces classname


    【解决方案1】:

    在这里查看:http://dotnetguts.blogspot.com/2008/12/reflection-in-c-list-of-class-name.html

    这里用于调用方法:http://www.csharphelp.com/archives/archive200.html

    如果您搜索更多这些链接中的术语,您会发现更多信息。

    【讨论】:

      【解决方案2】:

      在运行时命名空间只是成为类型名称的一部分。

      所以你需要:

      1. 加载程序集
      2. 获取所需类型的 Type 实例。
      3. 为您要调用的方法获取MethodInfo
      4. 调用方法。

      其中 2-4 个很容易。 1 可能容易或可能不容易,这取决于程序集所在的位置。假设可以通过正常的装配负载(“探测”)找到装配。这将调用一个不带参数但有返回值的类型的公共静态方法。

      var asm = Assembly.Load(assemblyName);
      var t = asm.GetType(typeName);
      // Pass array of parameter types to resolve between overloads (here no arguments).
      var m = t.GetMathod(methodName, BindingFlags.Static, null, new Type[] {}, null);
      // Pass no "this" or arguments.
      var res = (resultType) m.Invoke(null, null);
      

      这里的一些细节取决于你想要调用的程序集、类型和方法的细节。

      【讨论】:

        【解决方案3】:
               object result = null;
        
                using (StreamReader reader = new StreamReader(ASSEMBLYPATH, Encoding.GetEncoding(1252), false))
                {
                    byte[] b = new byte[reader.BaseStream.Length];
                    reader.BaseStream.Read(b, 0, Convert.ToInt32(reader.BaseStream.Length));
                    reader.Close();
        
                    Assembly asm = AppDomain.CurrentDomain.Load(b);
                    Type typeClass = asm.GetType(CLASSFULLNAME); // including namespace
                    MethodInfo mi = typeClass.GetMethod("OnStart");
                    ConstructorInfo ci = typeClass.GetConstructor(Type.EmptyTypes);
                    object responder = ci.Invoke(null);
        
                    // set parameters
                    object[] parameters = new object[1];
                    parameters[0] = null;  // no params
        
        
                    result = mi.Invoke(responder, parameters);
                }
        

        使用此代码的好处是程序集在使用后被卸载,因此您可以在调用方法后安全地删除dll。

        【讨论】:

          【解决方案4】:

          要加载程序集,您可以这样做:

          Assembly assembly = Assembly.LoadFile(@"test.dll");
          

          这假设您将磁盘上的程序集作为文件保存。如果您不这样做,例如从数据库中以字节数组的形式获取它们,Assembly 上还有其他方法可以帮助您在加载后为您提供一个 Assembly 对象。

          要遍历程序集中的所有类,您可以这样做:

          Assembly assembly = Assembly.LoadFile(@"test.dll");
          foreach (Type type in assembly.GetTypes())
          {
              if (type.IsClass)
              {
                  ...
              }
          }
          

          要找到 OnStart 静态方法,您可以这样做:

          Assembly assembly = Assembly.LoadFile(@"test.dll");
          foreach (Type type in assembly.GetTypes())
          {
              if (type.IsClass)
              {
                  MethodInfo method = type.GetMethod("OnStart",
                      BindingFlags.Static | BindingFlags.Public);
                  if (method != null)
                  {
                      ...
                  }
              }
          }
          

          要调用该方法,您可以这样做:

          Assembly assembly = Assembly.LoadFile(@"test.dll");
          foreach (Type type in assembly.GetTypes())
          {
              if (type.IsClass)
              {
                  MethodInfo method = type.GetMethod("OnStart",
                      BindingFlags.Static | BindingFlags.Public);
                  if (method != null)
                  {
                      method.Invoke(null, new Object[0]); // assumes no parameters
                      break; // no need to look for more methods, unless you got multiple?
                  }
              }
          }
          

          如果你需要给方法传递参数,你可以把它们放在一个对象数组中:

          Object[] arguments = new Object[] { arg1, arg2, arg3 ... };
          method.Invoke(null, arguments);
          

          上面的代码可以通过使用Linq为我们找到方法折叠成如下:

          Assembly assembly = Assembly.LoadFile(@"test.dll");
          var method = (from type in assembly.GetTypes()
                        where type.IsClass
                        let onStartMethod = type.GetMethod("OnStart",
                            BindingFlags.Static | BindingFlags.Public)
                        where onStartMethod != null
                        select onStartMethod).FirstOrDefault();
          if (method != null)
          {
              method.Invoke(null, new Object[0]); // assumes no parameters
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-20
            • 2012-04-30
            • 1970-01-01
            • 2013-02-22
            • 2016-02-09
            • 2019-06-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多