热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅析.Net共享程序集编程

作者:宋华赛迪网Net结构里的程序集Assembly是自我描述的安装单元,它在应用程序域(AppDomain)中运行。您必须首先将程序集加载到应用程序域中,然后才能运行该应用程序,并且,同一程序
作者:宋华   赛迪网
Net结构里的程序集Assembly是自我描述的安装单元,它在应用程序域(AppDomain)中运行。您必须首先将程序集加载到应用程序域中,然后才能运行该应用程序,并且,同一程序集可以加载到多个应用程序域中,根据这些应用程序域对该程序集代码使用方式的不同产生了程序集的分类:私有程序集和共享程序集。

1、私有程序集

我们通常用到的就是私有程序集。这种情况下,我们创建本地应用程序项目(或组件),编译后就生成dll或exe类型的私有程序程序集。当我们在其他客户应用程序中使用这类程序集时,只需要添加引用。当这样的程序集被多个应用程序域使用时,每个应用程序域需要复制该程序集,进程中也将存在该程序集的多个副本。

2、共享程序集

与私有程序集相对的是共享程序集(Shared Assembly),它提供多个应用程序域访问同一个程序集的能力,特别地,内存中只存在该程序集的同一份副本,这种非特定于域的代码共享极大节省了内存资源占用。并且,在大多数情况下,共享程序集安装在全局程序集高速缓冲存储器(Global Assembly Cache)中而不存在于应用程序相关目录下,对它的引用不会产生文件复制,自然也不会产生额外的副本。因而,共享程序集不能简单通过XCOPY命令实现部署,而应使用MSI(Microsoft Windows Installer)进行。当组件和主应用程序不由同一个开发商建立,或者一个大应用程序分布在几个小工程中时,常常需要使用共享程序集。

创建名称唯一的共享程序集


与私有程序集不同,使用共享程序集时要遵循许多规则。特别地,共享程序集必须有一个唯一的名称(称为强名StrongName)。这个名称被要求必须是全局唯一的,并且应该能够保护该名称,其他人不能再使用它创建同名程序集。一般地,我们通过嵌套命名空间层次结构来满足这一要求。结合公司名称、项目类别(类似文件夹分类)等命名项目类等对象,可以在一定程度上避免程序集重名。而配合使用公共/私有密钥机制,则可以彻底保证名称的唯一性。(关于密钥机制请参见专门的文章),下面简要说明强名称工具Sn.exe在这方面的应用:

生成公共/私有密钥对文件

.Net结构中的强名称工具Sn.exe有助于使用强名称对程序集进行签名,而通过签名具有强名称的程序集,就可以确保名称的全局唯一性。Sn.exe工具提供用于密钥管理、签名生成和签名验证的选项。其重要的一个应用是生成一个新的密钥对并将其写入指定的文件。引用这个密钥对文件的共享程序集将能够保证唯一的名称。

下面的命令行语句创建一个新的随机密钥对并将其存储在 myKey.snk 文件中。

sn -k myKey.snk

(Sn.exe还有很多参数,请参见Microsoft技术支持)

修改属性为程序集应用强名称

下一步,使用程序集属性将强名称信息引入代码中。属性AssemblyKeyFileAttribute指定包含用于生成共享名称的密钥对的文件名称,这个属性位于AssemblyInfo.cs文件中,该文件在使用Visual Studio.Net SDK创建项目时自动生成,用于保存程序集配置等信息。

在代码模块中,添加AssemblyKeyFileAttribute属性的同时指定在使用强名称为程序集签名时要用到的密钥对文件的名称及路径。下面的代码示例当前程序集与名为myKey.snk 的密钥文件一起使用:

[assembly:AssemblyKeyFileAttribute(@"../myKey.snk")](修改mykey.snk文件为正确的路径),这之后,如果使用Idasm工具查看该程序集,其清单中将包含一个公共密钥(私有密钥将不会保存在程序集清单中,这可以确保程序集不被非法修改)。

在全局程序集高速缓冲存储器GAC(Global Assembly Cache)中安装共享程序集


在我们使用Dll类型的私有程序集时,需要添加该程序集引用。而当私有程序集是exe类型时,还需要将它显式复制到当前应用程序的可执行目录(通常是当前工程的/Bin/Debug目录)中。其实,对DLL类型私有程序集的引用实质上也隐式进行了复制。添加应用后,在当前应用程序可执行目录或其子目录下,你就能够找到被引用的程序集文件(其实正是因为这样的特性,私有程序集安装很简单,只需复制改程序集中的所有文件,一个xcopy命令就足够了,这就是0压缩安装)。

与此类似,使用共享程序集也需要添加引用。不同的是,引用共享程序集不产生复制,而是在使用共享程序集前将其安装到全局程序集高速缓冲存储器GAC(Global Assembly Cache)中。.Net提供的命令行工具gacutil.exe用于支持这一功能。gacutil.exe可以将具有强名称的程序集添至全局程序集缓存。命令格式为:

      
       gacutil -I <程序集名称>
      


其中,"程序集名称"是要在全局程序集缓存中安装的程序集的名称。

下面的示例语句将文件名为 myAssembly.dll 的程序集安装到全局程序集缓存:

      
       gacutil -i myAssembly.dll
      


在客户应用程序中使用共享程序集


在客户应用程序中使用共享程序集的方法与私有程序集一样简单。创建客户应用程序后,以与引用私有程序集相同的方式引用共享程序集,在应用程序代码中包含共享程序集命名空间(using语句),这之后,你就可以象使用本地对象一样使用共享程序集的公共对象了。

综合上述,在.Net中使用VS.NET SDK进行共享程序集编程可分为以下步骤:

1)、生成共享程序集代码文件(组件、类库等)

2)、创建密钥文件并签名共享程序集

3)、在GAC中安装共享程序集

4)、在客户应用程序中使用共享程序集

下面的例子详细说明以上过程。为节省篇幅,示例使用控制台应用程序。Windows Forms应用程序中共享程序集编程与此类似。

1)、生成共享程序集代码文件

这里,创建一个的Windows Class Library 类库工程TestCreateSharedAssembly,它提供方法GetCreateDateTime()以返回文件的创建日期、时间信息。

      
       public string GetCreateDateTime(){DateTime dt=new DateTime();return dt.ToLongDateString();}
      


2)、创建密钥文件并签名共享程序集

首先,使用Sn.exe强名工具生成密钥对文件myKey.snk:

      
       Sn.exe -k myKey.snk;
      


然后,修改AssemblyInfo.cs文件以签名当前程序集:

      
       [assembly: AssemblyDelaySign(false)][assembly: AssemblyKeyFile(@"d:/winapp/myKey.snk")](请指定myKey.snk文件的正确路径)[assembly: AssemblyKeyName("")]
      


这之后,编译项目就将生成共享程序集TestCreateSharedAssembly.dll。

3)、在GAC中安装共享程序集

在程序集中包含了密钥对文件后,就可以使用全局程序集高速缓冲存储器gacutil的/I选项把它安装到全局程序集库(Global Assembly Store)中,下面的语句将前一步创建的共享程序集TestCreateSharedAssembly.dll安装到GAC中:

gacutil /I TestCreateSharedAssembly.dll

4)、在客户应用程序中使用共享程序集

现在,创建一个Windows Console控制台应用程序TestUseSharedAssembly。首先,引用前面创建的共享程序集TestCreateSharedAssembly.dll,这可以使用VS.Net主菜单(工程|添加引用)或集成解决方案Solution Explorer来完成,在点击它们的"浏览"按钮后的对话框中指定程序集TestCreateSharedAssembly.dll的正确路径完成引用。

在当前应用程序代码文件中,使用using语句包含欲使用共享程序集所在的命名空间TestCreateSharedAssembly,然后就可以象使用本地方法一样使用共享程序集的GetCreateTime()对象(包括属性、方法等)了。主要代码如下:

      
       using System;using TestCreateSharedAssembly;//引用共享程序集名称空间namespace TestUseSharedAssembly{class Class1{static void Main(string[] args){TestCreateSharedAssembly.Class1 tcsa=new TestCreateSharedAssembly.Class1();//实例化string datetime=tcsa.GetCreateDateTime();//调用所应用程序集的公共方法Console.WriteLine("Shared Assembly Create Time is:"+datetime);}}}
      


编译当前工程并在命令行中运行它,就会显示所引用共享程序集的创建日期和时间信息:

      
       Shared Assemby Create Time is:2002年12月10日
      

推荐阅读
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
author-avatar
撒药拿拉的唐小妄
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有