服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 动态加载程序集信息

C# 动态加载程序集信息

2021-12-28 16:44飞翔的月亮 C#

在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点。下面跟着小编一起来看下吧

 在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载dll需要的知识点。

涉及知识点:

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

如下图所示:

C# 动态加载程序集信息

具体代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
public partial class dllloadform : form
  {
    public dllloadform()
    {
      initializecomponent();
    }
    private void btnopenfile_click(object sender, eventargs e)
    {
      openfiledialog ofd = new openfiledialog()
      {
        multiselect=false,
        filter = "dll info|*.dll|all files|*.*",
initialdirectory=appdomain.currentdomain.basedirectory,
        title="dll信息",
        tag="请选择"
      };
      if (ofd.showdialog() == dialogresult.ok) {
        this.txtdllfile.text = ofd.filename;
      }
    }
    private void btnloaddll_click(object sender, eventargs e)
    {
      if (string.isnullorempty(this.txtdllfile.text.trim())) {
        messagebox.show("请选择dll文件");
        return;
      }
      loaddllinfo(this.txtdllfile.text);
    }
    /// <summary>
    /// 动态加载dll
    /// </summary>
    /// <param name="dllpath">需要加载的dll的路径</param>
    public void loaddllinfo(string dllpath)
    {
      if (file.exists(dllpath))
      {
        treenodecollection tvnodes = tvdllinfo.nodes;
        tvnodes.clear();
        tvnodes.add("dllinfo");
        assemblyname dllassemblyname = assemblyname.getassemblyname(dllpath);
        assembly dllassembly = assembly.load(dllassemblyname);
        module[] modules = dllassembly.getmodules();//获取作为程序集一部分的所有模块信息
        type[] types = dllassembly.gettypes();//获取程序集中定义的所有类型
        assemblyname[] referrenceasseblies = dllassembly.getreferencedassemblies();//获取程序集引用的程序集信息
        tvnodes[0].nodes.add("基本信息");
        string dllfullname = dllassembly.fullname;
        bool isglobalasseblycache = dllassembly.globalassemblycache;//是否从全局程序集加载
        bool isfulltrusted = dllassembly.isfullytrusted;//是否已完全信任方式加载的
        module manifestmodule = dllassembly.manifestmodule;//获取清单模块
        bool isreflectiononly = dllassembly.reflectiononly;//是否加载到只反射模块中
        //更新到节点
        tvnodes[0].nodes[0].nodes.add(string.format("全路径:{0}", dllfullname));
        tvnodes[0].nodes[0].nodes.add(string.format("是否全局程序集:{0}", isglobalasseblycache));
        tvnodes[0].nodes[0].nodes.add(string.format("是否全信任:{0}", isfulltrusted));
        tvnodes[0].nodes[0].nodes.add(string.format("是否只反射:{0}", isreflectiononly));
        tvnodes[0].nodes[0].nodes.add(string.format("清单模块:{0}", manifestmodule.name));
        ienumerable<type> exportedtypes = dllassembly.exportedtypes;//公共类型集合
        tvnodes[0].nodes.add("模块信息");
        int i = 0;
        foreach (var module in modules)
        {
          fieldinfo[] fields = module.getfields();//返回模块中定义的全局字段
          methodinfo[] methods = module.getmethods();//返回模块中定义的全局方法
          type[] mtypes = module.gettypes();//返回模块中定义的类型集合
          bool isresource = module.isresource();//指示此模块是否是资源
          int mdstreamversion = module.mdstreamversion;//获取源数据流的版本
          guid versionid = module.moduleversionid;//获取模块的版本id
          string modulename = module.name;//获取模块的名称,去除路径的
          int metadatatoken = module.metadatatoken;
          string scopename = module.scopename;
          tvnodes[0].nodes[1].nodes.add(string.format("模块:{0}", modulename));
          tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("数据流版本:{0}", mdstreamversion));
          tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("是否资源:{0}", isresource));
          tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("版本id:{0}", versionid));
          tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("metadata:{0}", metadatatoken));
          tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("scopename:{0}", scopename));
          tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<fieldinfo>(fields, "公共字段"));
          tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<methodinfo>(methods, "mehods"));
          //tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("types:{0}", string.join(",", mtypes.select(p => p.name))));
          i++;
        }
        tvnodes[0].nodes.add("类型信息");
        i = 0;
        foreach (var type in types)
        {
          typeattributes typeattributes = type.attributes;//与type关联的属性
          string typefullname = type.fullname;//获取类型的完全限定名称
          fieldinfo[] typefields = type.getfields();//获取所有的公共字段
          eventinfo[] typeevents = type.getevents();//获取所有的 公共事件
          type[] typeinterfaces = type.getinterfaces();//获取所有的公共接口
          memberinfo[] typemembers = type.getmembers();//获取所有的公共成员
          methodinfo[] typemethods = type.getmethods();//获取所有的公共方法
          typeinfo typeinfo = type.gettypeinfo();//返回指定类型的表述形式
          string namespace = type.namespace; //指定类型的命名空间
          string typename = type.name;//获取当前成员的名称
          constructorinfo[] typeconstructors = type.getconstructors();//类型的构造函数
          tvnodes[0].nodes[2].nodes.add(string.format("类型:{0}", typename));
          tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("全名称:{0}", typefullname));
          tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("制定类型名称:{0}", typeinfo.name));
          tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("命名空间:{0}", namespace));
          tvnodes[0].nodes[2].nodes[i].nodes.add(string.format("接口:{0}", string.join(",", typeinterfaces.select(p => p.name))));
          tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<fieldinfo>(typefields, "公共字段"));
          tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<constructorinfo>(typeconstructors, "构造函数"));
          tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<eventinfo>(typeevents, "事件"));
          tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<memberinfo>(typemembers, "成员member"));
          tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<methodinfo>(typemethods, "公共方法"));
          i++;
        }
      }
    }
    /// <summary>
    /// 通过类型获取节点
    /// </summary>
    /// <typeparam name="t"></typeparam>
    /// <param name="lstinfos"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public treenode getnodes<t>(t[] lstinfos, string name) where t : memberinfo
    {
      treenode tnode = new treenode(name);
      foreach (var t in lstinfos)
      {
        tnode.nodes.add(t.name);
      }
      return tnode;
    }
    /// <summary>
    /// 调用静态方法的例子
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btncallstaticbyreflection_click(object sender, eventargs e)
    {
      assemblyname assemblyname = assemblyname.getassemblyname("testassembly.exe");
      assembly assembly = assembly.load(assemblyname);
      type t = assembly.gettype("testassembly.program", true, true);
      //object o= activator.createinstance(t, false);
      methodinfo methodinfo = t.getmethod("main",bindingflags.static|bindingflags.public);
      methodinfo.invoke(null,new string[][] { new string[] { "g" } });
    }
    /// <summary>
    /// 调用非静态方法的例子
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btncallfunctionbyreflection_click(object sender, eventargs e)
    {
      assemblyname assemblyname = assemblyname.getassemblyname("testassembly.exe");//此处是相对路径
      assembly assembly = assembly.load(assemblyname);
      type t = assembly.gettype("testassembly.program", true, true);
      object o = activator.createinstance(t, false);
      methodinfo methodinfo = t.getmethod("testassembly", bindingflags.instance|bindingflags.public);
      object tmp= methodinfo.invoke(o,null);
      messagebox.show(tmp.tostring());
    }
  }

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!

原文链接:http://www.cnblogs.com/hsiang/p/6505568.html

延伸 · 阅读

精彩推荐
  • C#C#基础之泛型

    C#基础之泛型

    泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。接下来通过本文给大家介绍c#基础之泛型,感兴趣的朋友一起学习吧...

    方小白7732021-12-03
  • C#浅谈C# winForm 窗体闪烁的问题

    浅谈C# winForm 窗体闪烁的问题

    下面小编就为大家带来一篇浅谈C# winForm 窗体闪烁的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网7962021-12-21
  • C#Unity3D UGUI实现缩放循环拖动卡牌展示效果

    Unity3D UGUI实现缩放循环拖动卡牌展示效果

    这篇文章主要为大家详细介绍了Unity3D UGUI实现缩放循环拖动展示卡牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参...

    诗远3662022-03-11
  • C#c#学习之30分钟学会XAML

    c#学习之30分钟学会XAML

    一个界面程序的核心,无疑就是界面和后台代码,而xaml就是微软为构建应用程序界面而创建的一种描述性语言,也就是说,这东西是搞界面的...

    C#教程网8812021-12-10
  • C#C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    这篇文章主要介绍了C#实现的文件操作封装类,结合完整实例形式分析了C#封装文件的删除,移动,复制,重命名等操作相关实现技巧,需要的朋友可以参考下...

    Rising_Sun3892021-12-28
  • C#C# 后台处理图片的几种方法

    C# 后台处理图片的几种方法

    本篇文章主要介绍了C# 后台处理图片的几种方法,非常具有实用价值,需要的朋友可以参考下。...

    IT小伙儿10162021-12-08
  • C#C#直线的最小二乘法线性回归运算实例

    C#直线的最小二乘法线性回归运算实例

    这篇文章主要介绍了C#直线的最小二乘法线性回归运算方法,实例分析了给定一组点,用最小二乘法进行线性回归运算的实现技巧,具有一定参考借鉴价值,需要...

    北风其凉8912021-10-18
  • C#聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题,新手速来围观,一个通俗易懂的例子帮助大家更好的理解C#接口问题,感兴趣的小伙伴们可以参考一下...

    zenkey7072021-12-03