最近在做一款叫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. jstorm相关

    https://www.cnblogs.com/antispam/p/4182210.html

  2. 【UOJ224】短路

    具体可以看UOJmyy的blog,orz 就是一个贪心. #include<bits/stdc++.h> typedef long long ll; using namespace std ...

  3. 零基础学php的自学

    我们都知道,php语言作为一种专业建站的语言,没有华而不实,而是经受住了时间考验,成为一种值得学习的语言.现在国内众多的php学校也说明,php语言在当今有着广泛的市场需求. 那么零基础的同学如何学习 ...

  4. vue的data用到this问题

    问题:在vue中用vue-awesome-swiper,在data中初始化,用到swiper一个方法onTap,然后再调vue的一个函数,用到this,可是... data() { return { ...

  5. MYSQL 索引无效和索引有效的详细介绍

    1.WHERE字句的查询条件里有不等于号(WHERE column!=...),MYSQL将无法使用索引 2.类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)= ...

  6. java中的逻辑运算符,以及&与&&的区别,|与||的区别

    原创,转载请留言联系 逻辑运算符: & 与 false&true=false:true&true=true:false&false=false 必须两个都是true才返 ...

  7. html,获取iframe的window,document,自定事件与iframe通信

      获取iframe的window对象js代码如下.注意:一定要在文档加载完成之后,才能获取到 var Iframe=document.getElementById("script" ...

  8. Disruptor Ringbuffer

    系列译文: http://ifeve.com/disruptor/ 当有多个消费者时,(按Disruptor的设计)每个消费者各自控制自己的指针,依次读取每个Slot(也就是每个消费者都会读取到所有的 ...

  9. 181. Employees Earning More Than Their Managers

    The Employee table holds all employees including their managers. Every employee has an Id, and there ...

  10. AC日记——围栏木桩 洛谷 P2362

    围栏木桩 思路: DP: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 2001 int n,m,ai[ma ...