当前位置: 首页 > 编程日记 > 正文

程序集和应用程序域

这两个概念是DotNet程序员经常见到的,但好多人搞不清它们。虽然MSDN对它们有相关的说明,但并不是那么容易看懂。在这里灰灰虫根据自己的理解用简单易懂的语言解绍一下它们。
程序集(assembly)
    “程序集是包含编译好的、面向.NET Framework的代码的逻辑单元”
    这句话可以理解如下:
        首先:程序集是代码的逻辑单元,是逻辑上的概念。它不完全等价于编译好的DLL物理文件,但一般我们认为静态专用程序集与编译出的DLL文件或EXE文件是一致的。
        其次:它是被编译好的。它不是项目名称或命名空间,更不是源代码。
        最后:它是是面向.NET Framework的。意味着它虽然被编译了,但仍需要依托于.NET Framework来运行。
   
    一个程序集可以是一个包括元数据的DLL或EXE,也可以由多个文件组成,例如资源文件、元数据、DLL和EXE。
   
    注意:Win32的DLL(动态链接库)和DotNet中的DLL(程序集文件)的扩展名虽然都是DLL,但是二者内部的数据组织是不一样的,所以千万不要把二者混为一谈。
   
    程序集的分类:
        静态程序集和动态程序集:
        静态程序集:静态程序集包括中间语言元数据(MSIL,类似于Java字节码的东西),以及该程序集的资源(位图、JPEG 文件、资源文件等)。静态程序集存储硬盘文件中。
        动态程序集:动态程序集直接从内存运行并且在执行前不存储到磁盘上,如ASP.NET 2.0中的网站程序运行的时候产生的是动态程序集。
       
        专用程序集和共享程序集:
        专用程序集一般附带在某些软件上,且只为该软件提供专用的类库,这些库包含的代码只能用于该应用程序。一般专用程序集是与应用程序放在同一目录下的,在部署的时候与应用程序一起复制到目标机器上即可。
        共享程序集是其他应用程序可以使用的公共库,一般是安装到系统GAC中。因为其他软件可以访问共享程序集,所以所有共享程序集必须带有强名称(由发行者签名)。
   
    本地应用程序目录可用于存储专用程序集,所以专用程序集一般不会有版本冲突问题。其他应用程序都不会重写私有的程序集。当然,仍可以使用私有程序集的版本号,这样有助于代码的修改与管理,但它不是.NET所必须的。这种专用程序集是大多数程序员所喜欢的,它可以很好地避免DLL Hell的问题。但这种专用程序集只能部署在应用程序所在的目录之中,而无法像以往的Win32 DLL那样放置在System32目录中供多个应用程序共享,但有的时候设计人员仍有共享程序集的需求(把程序集部署到GAC目录中),这样一来又带来了我们似乎又看到DELL HELL又在慢慢地逼近我们,其实DLL共享程序集中根本不可能出现DELL HELL。因为共享程序集并不是简单地把私有程序集复制到GAC所在目录中,开发人员只能使用相关工具把强命名程序集(Strong-name Assembly)放在GAC所在目录中。在GAC中可以允许同名称但是不同版本号的程序集存在,当不同版本的强命名程序集安装在GAC中后,不同的应用程序会根据版本号信息去调用不同的程序集,这样就不会产生DLL程序集冲突的问题了。
   
    几个概念:
       DLL Hell(DLL地狱)
            在过去Win32程序中,DLL文件可以被安装在System32目录中,以供多个应用程序共享。
            但这种方式给我们带来了一个新的问题:DLL文件版本控制的问题。如果有两个软件共享同一个DLL,那如果其中一个软件版本升级后把这个DLL文件更新至一个新的版本,那另一个软件就无法再访问原来的DLL版本了。如果再安装第三个软件,这个软件也用到了这个DLL,但版本比现有的DLL版本还要低的话,那一旦产生DLL覆盖后那原有的软件就有可能不能再用了。这就是通常所说的DLL DELL。
      
       强命名程序集(Strong-name Assembly)
            强命名程序集要求设计人员为程序集指定版本号、区域、Private Key等信息,CLR则以此信息来找到正确的程序集。
            生成Private Key信息:
                sn -k c:\sgkey.snk      
            设置程序集的信息:

6898cd94217b2d10d31b700b.jpg


            其中黄色背景部分已过时了。应当如下设置:

fa8443f761ebc82c730eec14.jpg


            
       GAC(Global Assembly Cache-全局程序集缓存)
            GAC可以缓存全局使用的程序集,大多数共享程序集都安装在这个缓存中。它对应至硬盘上的一个目录(C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\GAC),不是所有的程序集文件复制到这个目录中就可以实现程序集共享的。要放在其中的程序集应当是强命名的程序集,GAC和强命名程序集实现的共享程序集才可以摆脱DLL DELL的困扰。
           将强命名程序集加载至GAC中:
                gacutil -i E:\Proj\ClassLibrary831\bin\Debug\ClassLibrary831.dll

754d5fce3b6c8537b700c811.jpg


            查看GAC中的所有的程序集:
                 gacutil -l   
            查看GAC中指定的程序集:
                 gacutil -l ClassLibrary831
            如果您将组成应用程序的某个程序集置于全局程序集缓存中,则将不再能够通过使用 xcopy 命令复制应用程序目录来复制或安装该应用程序。您还必须在全局程序集缓存中移动该程序集。
           
    程序集与命名空间的区别:
        一个程序集可以包含个命名空间,一个命名空间也可以跨越多个程序集。
        如果说命名空间是类库的逻辑组织形式,那么程序集就是类库的物理组织形式。只有同时指定所在命名空间和所在的程序集,才能完全限定类型。你要使用一个外部的类,必须引用该类所在的程序集,并且导入该类所在的命名空间。
        现在大家应当知道我们在使用某个外部的类时,为什么要在项目中“添加引用”相关的DLL文件,而且还要在代码中加入using ......了吧?

程序集与项目的区别:
        默认的情况下,项目名称和程序集的名称是一致的,但这并不代表二者是一个东西。
        项目是我们开发过程中概念,项目是用来统一管理我们开发过程的源代码等信息,创建不同的程序,我们应当建立不同的项目来管理。
        程序集是部署与使用中概念,它是我们程序编译出来的逻辑结果,作为静态程序集它对应着硬盘上的DLL文件。
        其实我们可以改变程序集的名称,使它和项目的名称不一致:

659482954efffd45d0135e16.jpg


        这样编译后,我们发现DLL文件名变为指定的程序集名称了。
        (车延禄)
应用程序域(AppDomain):
    在操作系统中,程序和程序之间应实现某种形式的隔离,防止程序和程序之间产生不可预知的影响,这种隔离是必须的。在DotNet技术之前,通常采用进程来形成隔离边界。每一个应用程序被加载到单独的进程中,每个进程都有其私有的内存,运行在一个进程中的应用程序不能写入另一个应用程序的内存,您也不能在两个进程间进行直接调用。
    在.NET结构中,应用程序有一个新的边界:应用程序域。应用程序域是一个用于隔离应用程序的“轻量级分界线”。所谓的“轻量级”是因为多个应用程序域可以存在于单个操作系统进程中。
    应用程序域可以确保在一个域中运行的代码不会影响进程中的其他应用程序;能够在不停止整个进程的情况下停止单个应用程序。

b67628d9286d072210df9b11.jpg


    进程2321有两个应用程序域。在应用程序域A中,实例化了对象1和2,对象1在程序集1中,对象2在程序集2中。在进程2322中,第二个应用程序域有实例1。实例和静态成员不能在应用程序域之间共享,也不能直接访问另一个应用程序域中的对象。
   
    AppDomain类用于创建和中断应用程序域,加载和卸载程序集。
    常用属性和方法:
        FriendlyName   取得应用程序域的友好名称
        CreateDomain()    创建新的应用程序域。
        ExecuteAssembly() 执行应用程序域中的程序集。它可用来执行另一个应用程序域中的代码。
        Unload() 执行域的正常卸载。只有应用程序域中正在运行的所有线程都已停止或域中不再有运行的线程之后,才卸载该应用程序域。

    创建应用程序域 :
    class AppDomain1
    {
        public static void Main()
        {
             Console.WriteLine("Creating new AppDomain.");
             //创建应用程序域
             AppDomain domain = AppDomain.CreateDomain("MyDomain");  
             //显示当前应用程序域的友好名称
             Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
             //显示新建应用程序域的友好名称
             Console.WriteLine("child domain: " + domain.FriendlyName);
        }
    }
   
    卸载应用程序域:
    class AppDomain2
    {
        public static void Main()
        {
             Console.WriteLine("Creating new AppDomain.");
             //创建应用程序域
             AppDomain domain = AppDomain.CreateDomain("MyDomain", null);
             Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
             Console.WriteLine("child domain: " + domain.FriendlyName);
             // 卸载应用程序域
             AppDomain.Unload(domain);
             Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
             //下面这行代码会产生异常,因为domain对象被卸载了
             Console.WriteLine("child domain: " + domain.FriendlyName);
         }
    }

将程序集加载到应用程序域中
    class AppDomain3
    {
        public static void Main(string[] args)
        {
            //取得当前应用程序域
            AppDomain ad = AppDomain.CurrentDomain;
            //加载ClassLibrary831应用程序集
            Assembly a = ad.Load("ClassLibrary831");
            //取得应用程序集中的NewClass类型
            Type t = a.GetType("ClassLibrary831.NewClass");
            //创建NewClass类型的实例
            object o = Activator.CreateInstance(t);
            //给对象的属性赋值
            PropertyInfo p1 = t.GetProperty("MyName");
            PropertyInfo p2 = t.GetProperty("MyInfo");
            p1.SetValue(o, "中国", null);
            p2.SetValue(o,"China",null);
            //调用对象的show方法
            MethodInfo mi = t.GetMethod("show");
            mi.Invoke(o, null);
        }
    }
   
    创建一个新的应用程序域,并加载执行程序集
    class Test
    {
        static void Main(string[] args)
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            Console.WriteLine(currentDomain.FriendlyName);
            //创建新的应用程序域
            AppDomain secondDomain = AppDomain.CreateDomain("New AppDomain");
            //在新的应用程序域中加载执行AssemblyA.exe程序集
            secondDomain.ExecuteAssembly("AssemblyA.exe");
        }
   }

转载于:https://www.cnblogs.com/30ErLi/archive/2010/09/17/1828970.html

相关文章:

股市币市:数据分析与交易所最新公告

投资原则: 极端牛市是攒钱的时候(分位数达到100),极端熊市是攒票的时候(分位数低于40%),股指已经屡创新高,你再不攒钱就不对了,同理,股指屡创新低&#xff0c…

OpenGL学习(hello)

#include <gl/glut.h>void display(void){glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲以及深度缓冲glColor3f(1.0, 1.0, 1.0);glBegin(GL_POLYGON); // 绘画開始话多边形/*glVertex3f(0.25, 0.25, 0.0);glVertex3f(0.75, 0.25, 0.0);glVertex3f(0.75, 0.75, 0.0);glV…

选择python培训机构的关键考核五大因素,让你永不吃亏!

近几年&#xff0c;对于Python技术在人工智能领域的广泛使用&#xff0c;想要学习Python技术的人越来越多&#xff0c;市面上的Python培训机构也多了起来&#xff0c;如何选择适合的Python培训机构成了困扰大家的问题&#xff0c;下面小编就我大家详细的解析一下选择python培训…

Maven 的classifier的作用

直接看一个例子&#xff0c;maven中要引入json包&#xff0c;于是使用了 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.2</version> </dependency> 可是&#xff0c;当…

NPOI 导出Excel

找到dll文件引用 using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System; using System.IO;namespace NPOI.WriteExcel {class Program{/*NPOI.DLL&#xff1a;NPOI 核心函式庫。NPOI.DDF.DLL&#xff1a;NPOI 繪圖區讀寫函式庫。NPOI.HPSF.DLL&#xff1a;NPOI 文…

如何利用 C# 实现 K 最邻近算法?

众所周知&#xff0c;电影可以按照题材分类&#xff0c;然而题材本身是如何定义的&#xff1f;由谁来判定某部电影属于哪个题材&#xff1f;也就是说同一题材的电影具有哪些公共特征&#xff1f;这些都是在进行电影分类时必须要考虑的问题。没有哪个电影人会说自己制作的电影和…

参加java培训真的能学到有用的吗

java技术在互联网行业的快速发展&#xff0c;优渥的待遇&#xff0c;让很多人都想学习这项技术&#xff0c;目前市面上开设java培训的机构越来越多&#xff0c;很多人都担心参加java培训能学到知识吗?下面我们来看看具体的解析。 参加java培训能学到知识吗?在Java培训机构能不…

android自定义调节器控件 —— RegulatorView

2019独角兽企业重金招聘Python工程师标准>>> RegulatorView效果图&#xff1a; RegulatorView实现步骤&#xff1a; 1.新建java类RegulatorView.java&#xff0c;继承View类 2.定义必要基础属性&#xff0c;及为其附初始值 private final static int BTN_RADIUS20;/…

如何利用 C# 实现 K-D Tree 结构?

我的朋友海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选&#xff0c;但她没有从中找到喜欢的人。经过一番总结&#xff0c;她发现曾交往过三种类型的人&#xff1a; 不喜欢的人魅力一般的人极具魅力的人 尽管发现了上述规律&#xff0c;但海…

[恩难到了]陨石的秘密

【描述】 公元19881231年&#xff0c;一颗巨大的陨石坠落在世界的政治文化中心cs。于是&#xff0c;灾难降临了&#xff0c;地球上出现了一系列反常的现象。当人们焦急万分的时候&#xff0c;一支由cs科学家组成的考察队赶到了出事地点。经过一番侦察&#xff0c;科学家们发现陨…

java培训学习阶段步骤讲解

目前的培训机构行业比较热门的IT技术就是java技术&#xff0c;java技术在近几年广受关注&#xff0c;java所涉及的技术知识也比较广泛&#xff0c;下面小编就为大家详细的介绍一下java培训学习多有哪几个阶段? java培训学习多有哪几个阶段&#xff1a; 第一阶段、Java设计和编…

资料分享:送你一本《机器学习实战》电子书!

这两天&#xff0c;各985高校发布了考研初试分数线。从中发现这两年大数据相关专业的分数线暴涨啊。没有400分估计心里都没底啊。可见大数据这个领域有多火爆&#xff01;而机器学习是我们团队的一个主要方向&#xff0c;新加入的同学通常都是从《机器学习实战》这本书开始入门…

HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5

思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Contest 5 题意&#xff1a;给出N个点的树&#xff0c;求去边的方案数使得 去边后最大匹配数是M的倍数限制&#xff1a; N<5e4, M<200 分析&#xff…

在别的电脑上运行cg程序出现错误的解决办法

错误&#xff1a;没有找到cg.dll&#xff0c;因为这个应用程序未能启动。重新安装应用程序可能会修复此问题 解决方法&#xff1a;复制cg.dll到system32 、debug中 错误&#xff1a;没有找到cgGL.dll&#xff0c;因为这个应用程序未能启动。重新安装应用程序可能会修复此问题 解…

HTML在网页设计中是什么作用?

HTML是一种超文本传输协议&#xff0c;规定了浏览器与服务端之间数据传输的格式&#xff0c;是一种标识性的代码语言&#xff0c;它的中文翻译是“超文本标记语言”&#xff0c;主要是通过HTML标签对网页中的文本、图片、声音等内容进行描述。HTML提供了许多标签&#xff0c;如…

如何实现链接只能被点击一次

有时候&#xff0c;只希望网站某个链接只能被点击一次&#xff0c;怎么做呢&#xff1f;下面给出3中方法&#xff01;第一种&#xff1a;利用JS在点击后把href变成#把taget变成空。 <p><a onclick"var that this;setTimeout(function(){that.removeAttribute(hr…

匿名类型和Object转换

.net中的匿名类型非常好用&#xff0c; 但是开发中遇到一个问题&#xff0c;当把匿名类型作为返回值的时候&#xff0c;会变成object类型&#xff0c;如果才能再转换能对应的匿名类型呢? 1 //返回匿名类型的函数, 会转换成object类型2 object ReturnAnonymous() {3 retur…

资料分享:送你一本《数据结构(C#语言版)》电子书!

对于信息类专业的学生而言&#xff0c;数据结构与算法是一门必修的课程。只有学好这门课程&#xff0c;熟练掌握线性表、栈、队列、树、图等基本结构&#xff0c;以及在这些结构上的各种算法&#xff0c;才能利用计算机去解决实际问题。 如何学好这门课程呢&#xff0c;给大家…

新手入门API测试必要了解的知识

什么是API?API是Application Programming Interface的简写。实现了两个或多个独立系统或模块间的通信和数据交换能力。 什么是API测试?API测试是不同于UI级自动化测试&#xff0c;其主要关注在系统架构的业务逻辑层&#xff0c;所以其主要关注不在于UI操作或用户感观上&#…

java监控多个线程的实现

场景&#xff1a;需要启动多线程处理事情&#xff0c;而在所有事情做完之后&#xff0c;需要修改系统状态&#xff1b;那么如何判断所有线程&#xff08;事情&#xff09;都做完了呢&#xff1f;这就需要判断所有当前运行的线程状态了。 代码 importjava.util.concurrent.Count…

如何利用 C# 实现神经网络的感知器模型?

前几天我们介绍了 如何利用 C# 对神经网络模型进行抽象&#xff0c;在这篇图文中&#xff0c;我们抽象了单个神经元 Neuro&#xff0c;网络层 Layer&#xff0c;网络结构 Network&#xff0c;激活函数 IActivationFunction&#xff0c;以及监督学习 ISupervisedLearning 和非监…

JPA增删改查,

2019独角兽企业重金招聘Python工程师标准>>> 1. //And --- 等价于 SQL 中的 and 关键字 public List<User> findByHeightAndSex(int height,char sex); 2. // Or --- 等价于 SQL 中的 or 关键字 public List<User> findByHeightOrSex(int height,cha…

Java新手会遇到的三大误区,一定要避免!

很多学习java技术的学员都是零基础学员&#xff0c;之前对java技术一点都不了解&#xff0c;所以java新手在学习java技术的时候很容易进入误区&#xff0c;下面小编分享的Java新手会遇到的三大误区&#xff0c;一定要避免! 作为目前最为广泛的网络编程语&#xff0c;Java凭借其…

[ACM] hdu 1253 胜利大逃亡 (三维BFS)

胜利大逃亡 Problem DescriptionIgnatius被魔王抓走了,有一天魔王出差去了,这但是Ignatius逃亡的好机会.魔王住在一个城堡里,城堡是一个A*B*C的立方体,能够被表示成A个B*C的矩阵,刚開始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,如今知道魔王将在T分钟后…

如何利用 C# 爬取带 Token 验证的网站数据?

在对文本数据的情感分析中&#xff0c;基于情感词典的方法是最简单也是最常用的一种了。 它的大体思路如下&#xff1a; 对文档分词&#xff0c;找出文档中的情感词、否定词以及程度副词&#xff0c;然后判断每个情感词之前是否有否定词及程度副词&#xff0c;将它之前的否定…

多线程显示运行状态

最近碰见一个例子&#xff0c;Copy大文件或者网络访问的时候处理假死。 那就用多线程加个进度条(只显示运行&#xff0c;没有进度)来表示状态运行吧。好了&#xff0c;废话少说&#xff0c;上个例子。先看结果图&#xff1a; 程序说明&#xff1a; 点击Button&#xff0c;运行…

【Python培训基础知识】单例模式

单例模式是保证一个类仅有一个实例的设计模式。Windows中的任务管理器就是一个典型的单例模式软件。Windows任务管理器如图所示。 Windows任务管理器只能打开一个&#xff0c;即使用户重复打开&#xff0c;也只能获得一个实例&#xff0c;这不同于Word等软件可以打开多个实例。…

Android读写XML(上)

XML 经常用作 Internet 上的一种数据格式&#xff0c;其文件格式想必大家都比较清楚&#xff0c;在这里我结合Android平台&#xff0c;来说明Android SDK提供的读写XML的package。 首先介绍下Android SDK与Java SDK在读写XML文件方面&#xff0c;数据包之间的关系。Android 平台…

Lighttpd1.4.20源代码分析 笔记 状态机之错误处理和连接关闭

这里所说的错误有两种&#xff1a; 1.http协议规定的错误&#xff0c;如404错误。 2.server执行过程中的错误。如write错误。 对于http协议规定的错误&#xff0c;这里的“错误”是针对client的。lighttpd返回相应的错误提示文件之后&#xff0c;相当于顺利的完毕了一次请求&…

资料分享:送你一本《数据结构(C语言版)》电子书!

要想写出可复用、可扩展、易维护、灵活性好的代码&#xff0c;「数据结构」这一关必须要过啊&#xff01; 在数据结构与算法的众多教材中&#xff0c;奉为经典的当属清华大学严蔚敏老师的著作。很多学校也选择这本书作为考研指定教材。 正在学习数据结构与算法这门课程的同学…