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

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#Unity3D实现虚拟按钮控制人物移动效果

    Unity3D实现虚拟按钮控制人物移动效果

    这篇文章主要为大家详细介绍了Unity3D实现虚拟按钮控制人物移动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    shenqingyu060520232410972022-03-11
  • C#C#设计模式之Visitor访问者模式解决长隆欢乐世界问题实例

    C#设计模式之Visitor访问者模式解决长隆欢乐世界问题实例

    这篇文章主要介绍了C#设计模式之Visitor访问者模式解决长隆欢乐世界问题,简单描述了访问者模式的定义并结合具体实例形式分析了C#使用访问者模式解决长...

    GhostRider9502022-01-21
  • C#C#通过KD树进行距离最近点的查找

    C#通过KD树进行距离最近点的查找

    这篇文章主要为大家详细介绍了C#通过KD树进行距离最近点的查找,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    帆帆帆6112022-01-22
  • C#C#实现XML文件读取

    C#实现XML文件读取

    这篇文章主要为大家详细介绍了C#实现XML文件读取的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Just_for_Myself6702022-02-22
  • C#C# 实现对PPT文档加密、解密及重置密码的操作方法

    C# 实现对PPT文档加密、解密及重置密码的操作方法

    这篇文章主要介绍了C# 实现对PPT文档加密、解密及重置密码的操作方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...

    E-iceblue5012022-02-12
  • C#WPF 自定义雷达图开发实例教程

    WPF 自定义雷达图开发实例教程

    这篇文章主要介绍了WPF 自定义雷达图开发实例教程,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下...

    WinterFish13112021-12-06
  • C#深入解析C#中的交错数组与隐式类型的数组

    深入解析C#中的交错数组与隐式类型的数组

    这篇文章主要介绍了深入解析C#中的交错数组与隐式类型的数组,隐式类型的数组通常与匿名类型以及对象初始值设定项和集合初始值设定项一起使用,需要的...

    C#教程网6172021-11-09
  • C#C#裁剪,缩放,清晰度,水印处理操作示例

    C#裁剪,缩放,清晰度,水印处理操作示例

    这篇文章主要为大家详细介绍了C#裁剪,缩放,清晰度,水印处理操作示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    吴 剑8332021-12-08