加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C# 动态加载程序集信息

发布时间:2020-12-16 01:14:08 所属栏目:百科 来源:网络整理
导读:本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。仅供学习分享使用,如有不足之处,还请指正。 在设计模式的策略模式中,需要动态加载程序集信息。 涉及知识点: AssemblyName类,完整描述程序集的唯一标识, 用来表述一个程序集。 Assembly类,在S

本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。仅供学习分享使用,如有不足之处,还请指正。

在设计模式的策略模式中,需要动态加载程序集信息。

涉及知识点:

  • AssemblyName类,完整描述程序集的唯一标识, 用来表述一个程序集。
  • Assembly类,在System.Reflection命名空间下,表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行时应用程序构建基块。
  • Module类 表述在模块上执行反射,表述一个程序集的模块信息。
  • Type类,在System命名空间下,表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
  • FieldInfo类,发现字段属性并提供对字段元数据的访问权。
  • MethodInfo类,发现方法的属性并提供对方法元数据的访问。
  • EventInfo类,发现事件的属性并提供对事件元数据的访问权。
  • ConstructorInfo类,发现类构造函数的属性并提供对构造函数元数据的访问权。
  • Activator类,包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。此类不能被继承。
  • BindingFlags类,指定控制绑定和由反射执行的成员和类型搜索方法的标志。在获取方法时,第二个参数会用到

效果图

如下图所示:

核心代码

具体代码如下:

  1 public partial class DllLoadForm : Form
  2     {
  3         public DllLoadForm()
  4         {
  5             InitializeComponent();
  6         }
  7 
  8         
  9 
 10         private void btnOpenFile_Click(object sender,EventArgs e)
 11  12             OpenFileDialog ofd = new OpenFileDialog()
 13             {
 14                 Multiselect=false, 15                 Filter = "Dll Info|*.dll|All Files|*.*" 16                 InitialDirectory=AppDomain.CurrentDomain.BaseDirectory,1)"> 17                 Title=Dll信息 18                 Tag=请选择"
 19             };
 20             if (ofd.ShowDialog() == DialogResult.OK) {
 21                 this.txtDllFile.Text = ofd.FileName;
 22             }
 23  24 
 25         void btnLoadDll_Click( 26  27             if (string.IsNullOrEmpty(this.txtDllFile.Text.Trim())) {
 28                 MessageBox.Show(请选择dll文件);
 29                 return;
 30  31             LoadDllInfo(.txtDllFile.Text);
 32  33 
 34         /// <summary>
 35         /// 动态加载Dll
 36         </summary>
 37         <param name="dllPath">需要加载的Dll的路径</param>
 38         void LoadDllInfo(string dllPath)
 39  40             if (File.Exists(dllPath))
 41  42                 TreeNodeCollection tvNodes = tvDllInfo.Nodes;
 43                 tvNodes.Clear();
 44                 tvNodes.Add(DllInfo 45                 AssemblyName dllAssemblyName = AssemblyName.GetAssemblyName(dllPath);
 46                 Assembly dllAssembly = Assembly.Load(dllAssemblyName);
 47                 Module[] modules = dllAssembly.GetModules();//获取作为程序集一部分的所有模块信息
 48                 Type[] types = dllAssembly.GetTypes();获取程序集中定义的所有类型
 49                 AssemblyName[] referrenceAsseblies = dllAssembly.GetReferencedAssemblies();获取程序集引用的程序集信息
 50                 tvNodes[0].Nodes.Add(基本信息 51 
 52                 string dllFullName = dllAssembly.FullName;
 53                 bool isGlobalAsseblyCache = dllAssembly.GlobalAssemblyCache;是否从全局程序集加载
 54                 bool isFullTrusted = dllAssembly.IsFullyTrusted;是否已完全信任方式加载的
 55                 Module manifestModule = dllAssembly.ManifestModule;获取清单模块
 56                 bool isReflectionOnly = dllAssembly.ReflectionOnly;是否加载到只反射模块中
 57                 更新到节点
 58                 tvNodes[0].Nodes[0].Nodes.Add(string.Format(全路径:{0} 59                 tvNodes[是否全局程序集:{0} 60                 tvNodes[是否全信任:{0} 61                 tvNodes[是否只反射:{0} 62                 tvNodes[清单模块:{0} 63                 IEnumerable<Type> exportedTypes = dllAssembly.ExportedTypes;公共类型集合
 64                 tvNodes[模块信息 65                 int i = 0 66                 foreach (var module in modules)
 67                 {
 68                     FieldInfo[] fields = module.GetFields();返回模块中定义的全局字段
 69                     MethodInfo[] methods = module.GetMethods();返回模块中定义的全局方法
 70                     Type[] mtypes = module.GetTypes();返回模块中定义的类型集合
 71                     bool isResource = module.IsResource();指示此模块是否是资源
 72                     int mdStreamVersion = module.MDStreamVersion;获取源数据流的版本
 73                     Guid versionId = module.ModuleVersionId;获取模块的版本ID
 74                     string moduleName = module.Name;获取模块的名称,去除路径的
 75                     int metadataToken = module.MetadataToken;
 76                     string scopeName = module.ScopeName;
 77                     tvNodes[1].Nodes.Add(模块:{0} 78                     tvNodes[1].Nodes[i].Nodes.Add(数据流版本:{0} 79                     tvNodes[是否资源:{0} 80                     tvNodes[版本ID:{0} 81                     tvNodes[MetaData:{0} 82                     tvNodes[ScopeName:{0} 83                     tvNodes[1].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(fields,公共字段));
 84                     tvNodes[1].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(methods,1)">Mehods 85                     tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("Types:{0}",string.Join(",",mtypes.Select(p => p.Name))));
 86                     i++ 87                 }
 88                 tvNodes[类型信息 89                 i =  90                 var type  types)
 91  92                     TypeAttributes typeAttributes = type.Attributes;与Type关联的属性
 93                     string typeFullName = type.FullName;获取类型的完全限定名称
 94                     FieldInfo[] typeFields = type.GetFields();获取所有的公共字段
 95                     EventInfo[] typeEvents = type.GetEvents();获取所有的 公共事件
 96                     Type[] typeInterfaces = type.GetInterfaces();获取所有的公共接口
 97                     MemberInfo[] typeMembers = type.GetMembers();获取所有的公共成员
 98                     MethodInfo[] typeMethods = type.GetMethods();获取所有的公共方法
 99                     TypeInfo typeInfo = type.GetTypeInfo();返回指定类型的表述形式
100                     string nameSpace = type.Namespace; 指定类型的命名空间
101                     string typeName = type.Name;获取当前成员的名称
102                     ConstructorInfo[] typeConstructors = type.GetConstructors();类型的构造函数
103                     tvNodes[2].Nodes.Add(类型:{0}104                     tvNodes[2].Nodes[i].Nodes.Add(全名称:{0}105                     tvNodes[制定类型名称:{0}106                     tvNodes[命名空间:{0}107                     tvNodes[接口:{0}",string.Join( p.Name))));
108                     tvNodes[2].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(typeFields,1)">109                     tvNodes[2].Nodes[i].Nodes.Add(GetNodes<ConstructorInfo>(typeConstructors,1)">构造函数110                     tvNodes[2].Nodes[i].Nodes.Add(GetNodes<EventInfo>(typeEvents,1)">事件111                     tvNodes[2].Nodes[i].Nodes.Add(GetNodes<MemberInfo>(typeMembers,1)">成员Member112                     tvNodes[2].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(typeMethods,1)">公共方法113                     i++114 
115 116 117 118 
119         120          通过类型获取节点
121         122         <typeparam name="T"></typeparam>
123         <param name="lstInfos"></param>
124         <param name="name"></param>
125         <returns></returns>
126         public TreeNode GetNodes<T>(T[] lstInfos,1)">string name) where T : MemberInfo
127 128             TreeNode tNode =  TreeNode(name);
129             var t  lstInfos)
130 131                 tNode.Nodes.Add(t.Name);
132 133              tNode;
134 135 
136         137          调用静态方法的例子
138         139         <param name="sender"></param>
140         <param name="e"></param>
141         void btnCallStaticByReflection_Click(142 143             AssemblyName assemblyName = AssemblyName.GetAssemblyName(TestAssembly.exe144             Assembly assembly = Assembly.Load(assemblyName);
145             Type t = assembly.GetType(TestAssembly.Programtrue,1)">true146             object o= Activator.CreateInstance(t,false);
147             MethodInfo methodInfo = t.GetMethod(MainBindingFlags.Public);
148             methodInfo.Invoke(null,1)">new string[][] { string[] { g } });
149 
150 151 
152         153          调用非静态方法的例子
154         155         156         157         void btnCallFunctionByReflection_Click(158 159             AssemblyName assemblyName = AssemblyName.GetAssemblyName(");此处是相对路径
160             Assembly assembly =161             Type t = assembly.GetType(162             object o = Activator.CreateInstance(t,1)">163             MethodInfo methodInfo = t.GetMethod(TestAssembly164             object tmp=  methodInfo.Invoke(o,1)">null165             MessageBox.Show(tmp.ToString());
166 167     }
View Code


----------------------------------------------------------------------

动态加载和反射调用的功能还有很多,不能一一列举,只能在以后的工作中用到时再加以研究。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读