从C#2.0中的dll获取Namespace,classname

时间:2009-10-20 09:36:33

标签: c# reflection namespaces classname

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

4 个答案:

答案 0 :(得分:12)

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

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
}

答案 1 :(得分:0)

点击此处:http://dotnetguts.blogspot.com/2008/12/reflection-in-c-list-of-class-name.html

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

如果您在这些链接中搜索更多条款,您会发现更多信息。

答案 2 :(得分:0)

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

所以你需要:

  1. 加载程序集
  2. 获取所需类型的Type实例。
  3. 获取您要拨打的方法的MethodInfo
  4. 调用方法。
  5. 这些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 :(得分:0)

       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。