谈谈.NET程序集(一)

谈谈.NET程序集(一)

The Assembly in .NET

by 唐小崇

http://www.cnblogs.com/tangchong

在.NET出现之前, Windows的程序有一些非常困扰人的问题:

1.当安装一个新的应用程序,有些时候会发现,它莫名其妙地损坏了已安装的应用程序(事实上是在系统的Win32文件夹内添加了与之前重名的dll文件,导致该dll被覆盖)。这种困境被称大家称为“DLL灾难”。

2.大部分的程序安装会影响到所有的系统部件。比如:要在不同的位置拷贝文件,要在注册表中添加信息。这个问题在于不能将应用程序作为一个单一的实体,这同时也导致了程序不便于拷贝/备份/部署。

3.安全问题。我们很难去保证程序的运行不会危害用户。

.NET程序 提出的程序集(Assembly)概念很好的解决了“DLL灾难”和部署难的问题,并且也提供一些安全保障。下面就让我们来谈谈程序集,程序集并不是一个单一的物理单位,它是由一个或者多个 包含元数据(Metadata)的托管模块(Managed Module)、一些资源文件 以及 清单 逻辑组成

一、托管模块(exe/dll)的相关概念

托管模块一般以.exe/.dll的形式出现,它们由面向CLR的编译器生成。它主要包含以下四个部分:

1、PE32/PE32+ header 。标准windows PE 头文件,主要指定了 该模块是32还是64位文件。还指定了给模块是GUI(exe),CUI(exe)或者DLL 其中的一种。

2、CLR header。CLR header 的定义在CorHdr.h文件中。它主要包含CLR版本、模块入口函数(Main函数)的 MethodDef 元数据、元数据的大小及偏移量、可选的强签名。

 3、Metadata。元数据是以二进制数据组成的块(a block of binary data)。它中包含3类表,分别是:定义表(definition tables)、引用表(reference tables)、清单表(manifest tables)。由于元数据提供如此完备的信息,使得程序集具有自描述的功能,从而解决了博客开头的前两个问题

·定义表(definition tables)  包含本模块内定义的 类型,方法,字段,参数,属性,事件。

    ·引用表(reference tables) 包含了本模块所引用的 数据集,模块,类型,方法,字段,属性,事件。

  ·清单表(manifest tables) 是描述整个程序集的表。它包含了程序集中所有文件的名称以及程序集的版本、文化、出版者、公开导出的类型。

托管模块通常包含定义表和引用表,而清单表一般给程序集使用的(下文会说到)。

我们可以用 ILDasm.exe来查看这些元数据。

 4、IL code。中间代码,编译器产生的面向CLR的代码。在运行时,CLR将其转换为本地CPU指令。

二、程序集

我们把一个或者多个托管模块,资源文件 组成一个程序集,同时,它有个专门的文件来保存 清单表元数据,这个清单包含了程序集中所有文件的名称以及程序集的版本、文化、出版者、公开导出的类型。

一定得注意的是:虽然托管模块具有我们常见的exe文件形式,但CLR操作的对象是程序集,而不是托管模块。CLR总是先加载清单文件,然后通过清单文件来获得其他文件的名称。虽然程序集可以只包含一个托管模块文件(exe)但是我们要以程序集为单位来进行操作,而不是一单个托管模块(exe)作为单位。

  ·程序集定义了可复用的类型(供其它程序集/模块 使用)

·程序集以版本号来标识

    ·程序集里包含安全相关的策略信息。

  CLR区分单个托管模块是否是程序集的方法是:查看它是否包含清单元数据表。

不用单个托管模块而用程序集做个一个执行单位 的好处是:

1、我们可以把不同作用的类型放在不同的文件(托管模块)中,在互联网中,可以以增量的形式下载文件。即需要用的时候再下载该部分文件

2、我们可以添加各种的资源、数据文件通过连接器链接到程序集中,比如Excel表,然后再程序里做好读取即可。

3、我们可以用不同的语言来生成不同功能的托管模块,这样每个语言的优势就体现出来了。

由于程序集有良好的自描述性,我们在部署(或者用户拷贝)程序集时,都非常方便。只要直接将程序集的文件拷贝到用户的磁盘中就好了,CLR会通过清单文件来找到各个所需文件。这样就避免在win32,注册表中放置文件,照成风险了。下图为一个程序集的示例:

 
 
分类: .NET
标签: .NET程序集元数据

.NET程序集1的更多相关文章

  1. 一次修改闭源 Entity Provider 程序集以兼容新 EntityFramework 的过程

    读完本文你会知道,如何在没有源码的情况下,直接修改一个 DLL 以去除 DLL 上的强命名限制,并在该程序集上直接添加你的“友元程序集(一种特殊的 Attribute,将它应用在程序集上,使得程序集内 ...

  2. 【.net 深呼吸】程序集的热更新

    当一个程序集被加载使用的时候,出于数据的完整性和安全性考虑,程序集文件(在99.9998%的情况下是.dll文件)会被锁定,如果此时你想更新程序集(实际上是替换dll文件),是不可以操作的,这时你得把 ...

  3. 【.net 深呼吸】跨应用程序域执行程序集

    应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...

  4. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  5. .NET 程序集单元测试工具 SmokeTest 应用指南

    Smoke Test(冒烟测试),也称Regression Test(回归测试),是对软件的安装和基本功能的测试.一般地我们使用脚本来实现Smoke Test的自动化,可借用虚拟机的snapshot机 ...

  6. MSSQLSERVER添加c# clr程序集的使用方法

    前言 MSSQLSERVER提供程序集,无疑可以让编程人员更加便捷的操作数据库数据,比如c#写的函数,可以在数据库当作sql的函数使用,你想想他对不熟悉数据库的程序员来说是有多么的嗨.这么好的机制,大 ...

  7. “前.NET Core时代”如何实现跨平台代码重用 ——程序集重用

    除了在源代码层面实现共享("前.NET Core时代"如何实现跨平台代码重用 --源文件重用)之外,我们还可以跨平台共享同一个程序集,这种独立于具体平台的"中性" ...

  8. 未能加载文件或程序集“Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5”或它的某一个依赖项。系统找不到指定的文件。

    在创建ASP.NET MVC项目过程中发生了这个异常 未能加载文件或程序集"Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0 ...

  9. 未能加载文件或程序集“System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。系统找不到指定的文件

    ASP.NET 运行时错误:针对类型System.Web.Mvc.PreApplicationStartCode的应用程序邓启动初始化方法Start 引发了异常,显示下列错误消息: 未能加载文件或程序 ...

  10. 比较.NET程序集(DLL或EXE)是否相同

    如何比较两个.NET程序集(DLL或EXE)是否相同呢? 直接比较文件内容?当然没那么简单了,这个你可以去试试,去比较一下两次Build产生的程序集, 就算内容没有改变,产生的程序集的二进制文件也是不 ...

随机推荐

  1. 使用Navicat Premium 和PL\SQL Developer连接Oracl

    在64位Win7中使用Navicat Premium 和PL\SQL Developer连接Oracle数据库备忘   最近接手了一个项目,服务器端数据库是oracle 11g 64位.由于主要工作不 ...

  2. FPGA 异步时钟处理方

    1 假设FPGA设计,包括不同的频率的时钟,它会发出涉及异步时钟. 我们需要一些方法来使时钟同步,从而保证FPGA可靠性设计. 2 在建立和保持时间所构成的有效时间窗体内,数据输入到触发器进行转换. ...

  3. 在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法

    在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法 罗朝辉 (http://blog.csdn.net/kesalin/) 本文遵循"署名-非商业 ...

  4. IOS启动其他应用程序

    从app1打开app2.主要的思路就是,能够为app2定义一个URL,在app1中通过打开这个URL来打开app2,在此过程中.能够传送一些參数. 在app1的代码中打开刚才定义的URL.代码例如以下 ...

  5. angularJS之站在jQuery的肩膀上

    jQuery:用更少的代码,实现更强悍的功能 托互联网日新月异发展的福,浏览器变成了人们接入互联网的入口,而JavaScript 这个曾经的小语种,终于成功地站到了舞台的中央,唤起了开发者的兴趣. 浏 ...

  6. 有空就写个C++程序

    近期工作变得轻松了非常多,有了一些空暇的时间,准备把大学时候的C++抓起来,而且研究研究算法: 第一个C++程序:计算圆的面积,也是看其它的博客写出来的C++程序. #include<iostr ...

  7. c语言发挥帕斯卡三角

    我们已经确定了帕斯卡三角的规则,下面是我的代码,非常实用哦! !! #include<stdio.h>  void main()  {      int i,j,n,k;      sca ...

  8. XAMPP on Mac 组态 Virual Host

    首先,在hosts文件中添加virtual host域名.方向127.0.0.1 我一般使用的命名约定dev-domainname.com sudo nano /private/etc/hosts # ...

  9. ”Validation of viewstate MAC failed” 错误

    ”Validation of viewstate MAC failed” 错误 在ASP.NET里面,View State使用较为广泛.它作为一个隐藏字段,可以帮助服务端”记住“客户端的改变,这样客户 ...

  10. IIS 5.x/6.0/7.0 和 ASP.NET

    原文:IIS 5.x/6.0/7.0 和 ASP.NET 本文主要介绍 3 个主要的 IIS 版本各自对 Web 请求的不同处理方式. 本文内容 IIS 5.x 和 ASP.NET IIS 6.0 和 ...