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

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#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05