最近在做一款叫VICA产品,此产品采用了插件机制,插件在运行中加载,插件与插件之间存在依赖关系,所有的插件DLL为方便管理都放置在Plugins的文件夹下统一管理。这种处理方式不自觉的就让我想了解clr对程序集的查找机制,根据经验,我想到了三种场景分析与实现。

第一种:所有的DLL都是动态加载,比如存在A,B两个dll,且A引用B,都是被动态加载,这也就意味着A,B都会在程序运行时加载到AppDomain里,那么执行到A程序集调用B程序集中的代码时,CLR会从AppDomain中查找B程序集,如果能找到则顺利调用,否则会抛出一个程序集B找不到的异常。针对此异常AppDomain发布了一个ResolveEventHandler事件,该事件的订阅者可根据实际情况手动指定程序集的物理位置再次加载返回。

结果:此分析正确,两个存在依赖关系的DLL如果都是动态加载,则在查找引用上不存在问题。

第二种:存在A,B两个DLL,A被编译时引用,B属于动态加载,此时我们按照第一种方式,在程序启动的时候分别将A,B动态记载到AppDomain中。

结果:程序刚启动就抛出了找不到A程序集的异常,这说明程序对dll的加载在我们手动加载前,此时A在Plugins文件夹下,我们没有在config中设置对此文件夹的查找,所以此分析也符合我们原有的知识。如果将A从Plugins文件夹在拿到Bin目录下,则结果正常运行,不会抛出找不到B的异常。

第三种:存在A,B两个DLL,A,B都被编译时引用,我们依然在程序启动时将A,B加载到AppDomain中,同时将A放置在Bin目录下,B放置在Plugins目录下,不对config做配置。

结果:程序运行到A调用B的时候 抛出找不到B,但是我们已经在调用A引用B的部分前将B程序集加载到AppDomain中,出现这个问题的原因,我还是没有找到,明明程序集B已经在AppDomain中,而我们的程序依然找不到B,我怀疑B其实和A一样,是在编译时已经确定好了一些约定,所以手动添加到AppDomain是无效的。只有B程序集属于动态添加时,才会重新从AppDomain中查找。对于第三种出现的情况,我们只能通过第一种场景中使用ResolveEventHandler事件来再次加载一边方能起作用。

以上三种场景其实真正被运用的主要是前两种,而至于第三种基本上不会被想到,但是从第三种情况我们了解到了一些clr查找DLL的原理。

.Net 有关程序集查找与加载的一点反思的更多相关文章

  1. 非常郁闷的 .NET中程序集的动态加载

    记载这篇文章的原因是我自己遇到了动态加载程序集的问题,而困扰了一天之久. 最终看到了这篇博客:http://www.cnblogs.com/brucebi/archive/2013/05/22/Ass ...

  2. .Net 程序集按需加载机制

    在开始本文之前先提两个疑问: 1.一个.Net程序依赖很多的dll,那个他们是在应用程序启动的时候全部把所依赖的动态库全部都加载到应用程序域中的呢还是有选择的加载呢? 2.当应用程序已经启动后我们动态 ...

  3. 未能从程序集“Oracle.ManagedDataAccess”加载 “OracleInternal.Common.ConfigBaseClass”

    使用VS2015做项目的过程中一直使用的服务器上的oracle数据库,后来想学习一下oracle,就在本机安装了oracle.可没想到本来运行好好的项目,现在不能运行了.项目是使用的Abp框架,当运行 ...

  4. CLR中的程序集加载

    CLR中的程序集加载 本次来讨论一下基于.net平台的CLR中的程序集加载的机制: [注:由于.net已经开源,可利用vs2015查看c#源码的具体实现] 在运行时,JIT编译器利用程序集的TypeR ...

  5. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)3---- 动态加载Assembly应用程序

    下载 supergraphfiles.exe 示例文件. 应用程序体系结构 在我专攻代码之前,我想谈谈我尝试做的事.您可能记得,SuperGraph 让您从函数列表中进行选择.我希望能够在具体的目录中 ...

  6. Assembly.Load动态加载程序集而不占用文件 z

    方式一:占用文件的加载 Assembly assembly = Assembly.Load(path); 用上面的方法可以动态的加载到dll,但是用这种方法加载到的dll一直到程序运行结束都是占用的d ...

  7. 重温CLR(十七)程序集加载和反射

    本章主要讨论在编译时对一个类型一无所知的情况下,如何在运行时发现类型的信息.创建类型的实例以及访问类型的成员.可利用本章讲述的内容创建动态可扩展应用程序. 反射使用的典型场景一般是由一家公司创建宿主应 ...

  8. 未能加载文件或程序集“XXXXXX”或它的某一个依赖项。试图加载格式不正确的程序。

    在本机WIN7机器上的WebService部署到Win2008R2上发现错误 “/”应用程序中的服务器错误. 未能加载文件或程序集“XXXXXX”或它的某一个依赖项.试图加载格式不正确的程序. 说明: ...

  9. C#如何加载程序运行目录外的程序集

    我们的应用程序部署的时候,目录结构一般不会只有运行程序的目录这一个,我们可能在运行目录下建子目录,也可能使用System32目录,也可能使用其它第三方的程序集..Net程序集 首先会在GAC中搜索相应 ...

随机推荐

  1. 【LabVIEW技巧】你可以不懂OOP,却不能不懂封装

    前言 大多数写LabVIEW程序的工程师都不是一个纯软的工程师,很多做硬件的.做机械的.甚至学化学的也会学习LabVIEW. 由于主要重心不在软件,所以LabVIEW程序基本上能用行,也就得到入门容易 ...

  2. eetcode 之String to Integer (atoi)(28)

    字符串转为数字,细节题.要考虑空格.正负号,当转化的数字超过最大或最小是怎么办. int atoi(char *str) { int len = strlen(str); ; ; ; while (s ...

  3. poj 2452(RMQ+二分查找)

    题目链接: http://poj.org/problem?id=2452 题意:在区间[1,n]上找到满足 a[i]<a[k]<a[j] (i<=k<=j) 的最大子区间 (j ...

  4. 微信小程序 - 时间进度条功能

    关于答题类,或者一些游戏环节的小程序需要用到时间进度条,改功能怎么实现看下面源码 <view class='out' style='margin-top:10px'> <view c ...

  5. Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up

    http://mail-archives.apache.org/mod_mbox/cloudstack-users/201306.mbox/%3c201306181058330006472@gmail ...

  6. 【剑指offer】面试题 29. 顺时针打印矩阵

    面试题 29. 顺时针打印矩阵 题目描述 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  7. keycloack docker 本地运行

    参考github地址:https://github.com/jboss-dockerfiles/keycloak 首先使用git 下载该项目 使用docker-compose运行项目,需要进入至doc ...

  8. 使用mongo shell和客户端连接至MongoDB Atlas

    MongoDB Atlas是Mongo官方的一个集群服务,也可以注册并创建一个免费的集群,但DB的大小只有500M,如果数据量不是很大的应用,可以选择该集群方案 需要注意的是,目前我使用的这个集群,服 ...

  9. thinkjphp 模板中获取url中的action

    <if condition="ACTION_NAME eq 'add'">新增<else/>编辑</if>

  10. (2)go 规范,变量,基本数据类型

    .一.规范 main 函数为入口 严格区分大小写 不需要加分号 一行只写一条语句 定义的变量或者导入的包必须要用到,否则编译时会报错 左括号不能单独一行 逗号可以用来在换行时连接字符串 标识符由字母数 ...