如何通过反射获取一个dll引用,依赖注入 循环引用的其它程序集

2012年 总版技术专家分年内排行榜第一
2013年 总版技术专家分年内排行榜第七2011年 总版技术专家分年内排行榜第五2009年 总版技术专家分年内排行榜第九
2015年4月 荣获微软MVP称号2014年4月 荣获微软MVP称号
2014年12月 企业软件大版内专家分月排行榜第一2014年11月 企业软件大版内专家分月排行榜第一2014年7月 企业软件大版内专家分月排行榜第一2011年10月 企业开发大版内专家分月排行榜第一2011年5月 企业开发大版内专家分月排行榜第一2011年3月 企业开发大版内专家分月排行榜第一2010年12月 企业开发大版内专家分月排行榜第一2010年11月 企业开发大版内专家分月排行榜第一2010年9月 企业开发大版内专家分月排行榜第一2010年8月 企业开发大版内专家分月排行榜第一2010年7月 企业开发大版内专家分月排行榜第一2010年6月 企业开发大版内专家分月排行榜第一2010年5月 企业开发大版内专家分月排行榜第一
2013年 总版技术专家分年内排行榜第一
2014年 总版技术专家分年内排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。//这个是反射查找的C#写的com组件,没问题。可以找到。
assembly&=&Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory&+&&MyLib.dll&);
//但是这个调用C++写的com组件就不行了,C++com组件在debug下是叫&DVBusinessCom.dll但是我试了下引用的话,引用在项目当中它会在项目当中自己就多了个lib成DVBusinessComLib所以查找不到。
assembly&=&Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory&+&&DVBusinessCom.dll&);
&还请各位大神给支个招!~~
回复讨论(解决方案)
直接反射C++写的Dll是反射不了的。
再用C#写一个包含DVBusinessCom.dll里面方法的dll,放到同路径下,然后反射.NET版本的dll
直接反射C++写的Dll是反射不了的。
再用C#写一个包含DVBusinessCom.dll里面方法的dll,放到同路径下,然后反射.NET版本的dll
&这样做的话没什么意义了啊,我想的能够动态加载DLL文件里面的方法,我写个方法只需要知道方法名参数,然后让她自己去dll文件里面找到那个方法。。!~
直接反射C++写的Dll是反射不了的。
再用C#写一个包含DVBusinessCom.dll里面方法的dll,放到同路径下,然后反射.NET版本的dll
&这样做的话没什么意义了啊,我想的能够动态加载DLL文件里面的方法,我写个方法只需要知道方法名参数,然后让她自己去dll文件里面找到那个方法。。!~
没错啊,就是这样啊,又没叫你用C#重新实现一遍,只是用C#做一层包装而已
C#反射不了C++&dll,只能DllImport调用C++&dll
C#反射不了C++&dll,只能DllImport调用C++&dll
&&//声明一个反射类对象
&&&&&&&&&&&&&&&&&&&&Assembly&
&&&&&&&&&&&&&&&&&&&&//让这个对象加载某个外部dll程序集信息.
&&&&&&&&&&&&&&&&&&&&//assembly&=&Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory&+&&MyLib.dll&);
&&&&&&&&&&&&&&&&&&&&assembly&=&Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory&+&&DVBusinessCom.dll&);
&&&&&&&&&&&&&&&&&&&&//Assembly.
&&&&&&&&&&&&&&&&&&&&//定义一个&类型信息&的对象.
&&&&&&&&&&&&&&&&&&&&Type&type&=&assembly.GetType(&MyLib.Class1&,&false,&true);
&&&&&&&&&&&&&&&&&&&&//定义一个成员信息类对象数组,并从程序集中获取.
&&&&&&&&&&&&&&&&&&&&MemberInfo[]&info&=&type.GetMembers();
&&&&&&&&&&&&&&&&&&&&//定义一个成员方法对象,这里是指定方法名称来获取的.
&&&&&&&&&&&&&&&&&&&&MethodInfo&method&=&type.GetMethod(args[0]);
&&&&&&&&&&&&&&&&&&&&List&object&&result&=&new&List&object&();
&&&&&&&&&&&&&&&&&&&&for&(int&i&=&1;&i&&&args.L&i++)
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&result.Add(int.Parse(args[i]));
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&object[]&arg&=&result.ToArray();
&&&&&&&&&&&&&&&&&&&&//创建类的实例
&&&&&&&&&&&&&&&&&&&&object&instance&=&assembly.CreateInstance(&MyLib.Class1&);
&&&&&&&&&&&&&&&&&&&&int&s&=&(int)method.Invoke(instance,&arg);
&&&&&&&&&&&
Console.Write(&返回值为:&+s).ToString());
类似这种的功能,,我改怎么实现呢?
是不是思路不对?
对于COM组件,都有一个公开的组件类名(在注册表的HKEY_CLASSES_ROOT下),以及关联的ProgID(GUID形式的唯一标识),有了它,就可以从ROT(运行对象表)获取一个COM对象指针,并调用功能函数
VB是弱类型的,所以不需要反射,只需要GetObjet(,&COM类名&)就行,C#中对应的方法是Marshal.GetActiveObject()
type&=&System.Type.GetTypeFromCLSID(GUID)&也就是你上面要反射的类型
appComObject&=&Activator.CreateInstance(type)
还是用弱类型对象避开类型检查方便点(COM编程的一个缺点),比如用VB.Net或者C#4.0中的动态类型对象
是不是思路不对?
对于COM组件,都有一个公开的组件类名(在注册表的HKEY_CLASSES_ROOT下),以及关联的ProgID(GUID形式的唯一标识),有了它,就可以从ROT(运行对象表)获取一个COM对象指针,并调用功能函数
VB是弱类型的,所以不需要反射,只需要GetObjet(,&COM类名&)就行,C#中对应的方法是Marshal.GetActiveObject()
type&=&System.Type.GetTypeFromCLSID(GUID)&也就是你上面要反射的类型
appComObject&=&Activator.CreateInstance(type)
还是用弱类型对象避开类型检查方便点(COM编程的一个缺点),比如用VB.Net或者C#4.0中的动态类型对象
&试了下,果然这个可以,谢谢!~结贴了。。&&& 在开发中,经常会遇到这种情况,在A.dll中需要反射B.dll中的类型,如果稍不注意,就会产生运行时错误。关于跨程序集的反射,记住两点就可以:(1)如果使用typeof,编译能通过,则跨程序集的反射一定可以正常运行。可以说,typeof是支持强类型的。比如
Type&supType&=&typeof(EnterpriseServerBase.DataAccess.IDBAccesser)&;
&&& 如果当前程序集没有添加对EnterpriseServerBase.dll的引用,则编译会报错。(2)如果使用Type.GetType,情况就复杂些,这是因为Type.GetType是非强类型的。Type.GetType的参数是一个string,当string表示的目标类型不在当前程序集中,则运行时Type.GetType会返回null。解决的办法是:首先加载目标程序集,然后再使用Assembly.GetType方法。如
&&&&&&&&&&& Assembly&asmb&=&Assembly.LoadFrom("EnterpriseServerBase.dll")&;&&&&&&&&&&&&Type&supType&=&asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser")&;
&&&&注意,当使用Type.GetType的时候,即使你添加了对EnterpriseServerBase.dll的引用,Type.GetType("EnterpriseServerBase.DataAccess.IDBAccesser")也会返回null,这是因为Type.GetType只会在当前程序集中进行类型搜索!
阅读(...) 评论()15015人阅读
我の原创(116)
.NET(51)
C#反射获取程序集信息和通过类名创建类实例 。
System.Reflection 命名空间:包含通过检查托管代码中程序集、模块、成员、参数和其他实体的元数据来检索其相关信息的类型。
Assembly 类:表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行库应用程序构造块。
1、反射获取程序集信息
1.1 创建AssemblyResult.cs类,用于保存结果
/// &summary&
/// 反射结果类
/// &/summary&
public class AssemblyResult
/// &summary&
/// 程序集名称
/// &/summary&
public List&string& AssemblyName { }
/// &summary&
/// &/summary&
public List&string& ClassName { }
/// &summary&
/// 类的属性
/// &/summary&
public List&string& Properties { }
/// &summary&
/// 类的方法
/// &/summary&
public List&string& Methods { }
1.2 创建AssemblyHandler.cs反射处理类
注意:要引用System.Reflection 命名空间。
using System.Collections.G
using System.L
using System.T
using System.R
using System.IO;
namespace MyStudyFrom
/// &summary&
/// 反射处理类
/// &/summary&
public class AssemblyHandler
string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @&/MyDLL/&;
/// &summary&
/// 获取程序集名称列表
/// &/summary&
public AssemblyResult GetAssemblyName()
AssemblyResult result = new AssemblyResult();
string[] dicFileName = Directory.GetFileSystemEntries(path);
if(dicFileName!=null)
List&string& assemblyList = new List&string&();
foreach(string name in dicFileName)
assemblyList.Add(name.Substring(name.LastIndexOf('/') + 1));
result.AssemblyName = assemblyL
/// &summary&
/// 获取程序集中的类名称
/// &/summary&
/// &param name=&assemblyName&&程序集&/param&
public AssemblyResult GetClassName(string assemblyName)
AssemblyResult result = new AssemblyResult();
if (!String.IsNullOrEmpty(assemblyName))
assemblyName = path + assemblyN
Assembly assembly = Assembly.LoadFrom(assemblyName);
Type[] ts = assembly.GetTypes();
List&string& classList = new List&string&();
foreach (Type t in ts)
//classList.Add(t.Name);
classList.Add(t.FullName);
result.ClassName = classL
/// &summary&
/// 获取类的属性、方法
/// &/summary&
/// &param name=&assemblyName&&程序集&/param&
/// &param name=&className&&类名&/param&
public AssemblyResult GetClassInfo(string assemblyName, string className)
AssemblyResult result = new AssemblyResult();
if (!String.IsNullOrEmpty(assemblyName) && !String.IsNullOrEmpty(className))
assemblyName = path + assemblyN
Assembly assembly = Assembly.LoadFrom(assemblyName);
Type type = assembly.GetType(className,true,true);
if (type != null)
//类的属性
List&string& propertieList = new List&string&();
PropertyInfo[] propertyinfo = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (PropertyInfo p in propertyinfo)
propertieList.Add(p.ToString());
result.Properties = propertieL
//类的方法
List&string& methods = new List&string&();
MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo mi in methodInfos)
methods.Add(mi.Name);
//方法的参数
//foreach (ParameterInfo p in mi.GetParameters())
//方法的返回值
//string returnParameter = mi.ReturnParameter.ToString();
result.Methods =
2、通过类名创建类实例
2.1、假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型):
Assembly assembly = Assembly.LoadFile(&程序集路径,不能是相对路径&); // 加载程序集(EXE 或 DLL)
object obj = assembly.CreateInstance(&类的完全限定名(即包括命名空间)&); // 创建类的实例&
2.2、若要反射当前项目中的类可以为:
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
object obj = assembly.CreateInstance(&类的完全限定名(即包括命名空间)&); // 创建类的实例,返回为 object 类型,需要强制类型转换
2.3、也可以为:
Type type = Type.GetType(&类的完全限定名&);
object obj = type.Assembly.CreateInstance(type);
=======================================================
1)反射创建某个类的实例时,必须保证使用类的完全限定名(命名空间 + 类名)。Type.GetType 方法返回 null 则意味搜索元数据中的相关信息失败(反射失败),请确保反射时使用类的完全限定名。
2)反射功能十分强大,没有什么不能实现的。若实现“跨程序集”,请使用第一种方法创建类的实例,并反射该实例的字段、属性、方法、事件... 然后动态调用之。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:671993次
积分:6124
积分:6124
排名:第3215名
原创:117篇
转载:32篇
评论:69条
(2)(1)(4)(7)(6)(3)(1)(2)(5)(5)(4)(2)(3)(6)(2)(3)(7)(4)(1)(6)(8)(5)(7)(3)(2)(4)(4)(8)(2)(2)(2)(5)(1)(1)(2)(1)(1)(1)(9)(1)(1)(1)(3)(1)

我要回帖

更多关于 c 依赖注入 反射 的文章

 

随机推荐