从 C# 2.0 中的 dll 获取命名空间、类名
Posted
技术标签:
【中文标题】从 C# 2.0 中的 dll 获取命名空间、类名【英文标题】:Get Namespace, classname from a dll in C# 2.0 【发布时间】:2010-12-08 06:54:18 【问题描述】:我将动态获取 dll。我需要加载 dll 并获取命名空间、类名来调用方法(方法名称是静态的,它始终是“OnStart()”)。 基本上我需要通过加载dll来运行一个方法。有人可以帮忙吗!!!。
【问题讨论】:
【参考方案1】:在这里查看:http://dotnetguts.blogspot.com/2008/12/reflection-in-c-list-of-class-name.html
这里用于调用方法:http://www.csharphelp.com/archives/archive200.html
如果您搜索更多这些链接中的术语,您会发现更多信息。
【讨论】:
【参考方案2】:在运行时命名空间只是成为类型名称的一部分。
所以你需要:
-
加载程序集
获取所需类型的 Type 实例。
为您要调用的方法获取
MethodInfo
。
调用方法。
其中 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
【讨论】:
以上是关于从 C# 2.0 中的 dll 获取命名空间、类名的主要内容,如果未能解决你的问题,请参考以下文章