扫盲--.net 程序集

时间:2022-12-24 10:22:45

前言:用了几天的时间把高级编程里面程序集一章看完了,原来自己只知道写代码,右键添加引用,从来也不知道操作的实质是什么,微软总是这个套路,鼠标点点就能把任务完成,这对新手友好但是对要通透了解程序执行和内部原理的程序员来说真是有点膈应。

程序集的概述

1.1程序集定义

程序集是 .net 应用程序的部署单元。.net应用程序包含一个或多个程序集。通常拓展名是exe或dll的 .net可执行文件被称为程序集。

程序集是自我描述的安装单元,由一个或多个文件组成。

程序集可以是私有的或共享的。在简单的 .net应用程序中,最好使用私有程序及工作。私有程序集没有特殊的管理、注册和版本设置的问题。

1.2程序集的功能

程序集的功能总结如下:

  • 程序集是自描述的。不在需要考虑注册表键,从其他地方获得类型库等问题。程序集包含了描述程序集的元数据。元数据包括从程序集中导出的类型和一个清单。
  • 版本的相互依赖性在程序集的清单中进行的记录。
  • 程序集可以并行加载,同一个DLL的不同版本可以在系统上同时使用。
  • 应用程序使用应用程序域来确保其独立性。使用应用程序域,许多应用程序就可以独立的运行在一个机制中。一个应用程序中的错误不会直接影响同一个进程中的其他应用程序。

    1.3程序集的结构

    程序集由描述它的程序集元数据,描述导出赖幸和方法的类型元数据,MSIL代码和资源。所有的这些部分都在一个文件中,或者分布在几个文件中。

扫盲--.net 程序集

(太具体的知识涉及到IL,作为程序开发,如果不是有需要我觉得没有必要深究)

1.4 程序集清单

程序集清单是元数据的一部分,描述了程序集和引用它所需要的所有信息,并列出来它所有的依赖关系。清单有以下部分组成:

  • 标识(名称,版本,区域性和公钥)
  • 属于该程序集的一个文件列表。一个程序集只要要有一个文件,也可以包含多个文件。
  • 被引用程序集的列表。在程序集清单中说明了再程序集中使用的所有程序集,这些引用信息包括版本信息和公钥。公钥用于唯一地标识程序集。
  • 一组许可请求————运行这个程序集需要的许可。
  • 导出类型。

    1.5 程序集的特性

    在创建Visual Studio项目时,会自动生成AssemblyInfo.cs,这个文件用于配置程序集清单,编译器读取特性,把特定的信息插入到程序集清单中。

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// 有关程序集的常规信息通过以下 // 特性集控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("StrongNameTest")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("StrongNameTest")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 使此程序集中的类型 // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, // 则将该类型上的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("3583900e-78ff-4a15-9168-ad05faf1e0fd")] // 程序集的版本信息由下面四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] 

诸如引用秘钥文件为程序集创建强命的操作都可以在这里配置


程序集和应用程序域的关系

在 .net之前的技术中,进程作为独立的边界来使用,每个进程都有其私有的虚拟内存;运行在一个进程的应用程序不能写入另个一个应用程序的内存,也不会因为这种方式破坏其他的应用程序。该进程引用程序之间的一个独立安全的边界。在 .net体系结构中,应用程序有一个新的边界:应用程序域。使用托管IL代码,运行库可以确保在同一个进程中不能访问另一个应用程序的内存。
多个应用程序可以运行在一个进程的多个应用程序域中。
和一个完整的进程相比,应用程序域的CPU和内存占用要小的多。因此CLR加载和卸载应用程序域比起完整的进程来说也快的多。

在 .net中,AppDomain类是用来操作应用程序域的,具体代码操作在AppDomain操作

下面是程序集的简单操作

      static void Main(string[] args) { AppDomain currentAppDomain = AppDomain.CurrentDomain; Console.WriteLine(currentAppDomain.FriendlyName); AppDomain secondDomain = AppDomain.CreateDomain("New AppDomain"); // secondDomain.ExecuteAssembly("TestAppDomain.exe"); secondDomain.CreateInstance("TestAppDomain", "TestAppDomain.Demo", true, BindingFlags.CreateInstance, null, new object[] { 7, 3 }, null, null); Console.ReadKey(); }

共享程序集

程序集可以由一个应用程序单独使用,在默认情况下不共享程序集。在使用共享程序集是,需要考虑一些特定的要求。

2.1强命

自己的理解,.net中强命的设计是GUID+摘要算法+非对称加密

  • GUID保证共享程序集名称是全局唯一的
  • 摘要算法保证内容不被篡改
  • 非对称加密保证发布者合法,对摘要算法结果进行加密保证文件不被篡改

2.2全局程序集缓存

顾名思义,全局程序集缓存(Global Assembly Cache)就是可全局使用的程序集的缓存。大多数共享程序集都安装在这个缓存中;另外,也可以使用共享目录(也在服务器上)。

GAC位于\assembly目录下。

gacutil.exe 实用工具可以使用命令行安装、卸载和显示程序集。更加具体的操作在博客园地址中留作备用,这里就不赘述了。

先写这么多吧,感觉更多的东西需要工作中再补充,这里总结只是一些概念