.Net 有关程序集查找与加载的一点反思
最近在做一款叫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 有关程序集查找与加载的一点反思的更多相关文章
- 非常郁闷的 .NET中程序集的动态加载
记载这篇文章的原因是我自己遇到了动态加载程序集的问题,而困扰了一天之久. 最终看到了这篇博客:http://www.cnblogs.com/brucebi/archive/2013/05/22/Ass ...
- .Net 程序集按需加载机制
在开始本文之前先提两个疑问: 1.一个.Net程序依赖很多的dll,那个他们是在应用程序启动的时候全部把所依赖的动态库全部都加载到应用程序域中的呢还是有选择的加载呢? 2.当应用程序已经启动后我们动态 ...
- 未能从程序集“Oracle.ManagedDataAccess”加载 “OracleInternal.Common.ConfigBaseClass”
使用VS2015做项目的过程中一直使用的服务器上的oracle数据库,后来想学习一下oracle,就在本机安装了oracle.可没想到本来运行好好的项目,现在不能运行了.项目是使用的Abp框架,当运行 ...
- CLR中的程序集加载
CLR中的程序集加载 本次来讨论一下基于.net平台的CLR中的程序集加载的机制: [注:由于.net已经开源,可利用vs2015查看c#源码的具体实现] 在运行时,JIT编译器利用程序集的TypeR ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)3---- 动态加载Assembly应用程序
下载 supergraphfiles.exe 示例文件. 应用程序体系结构 在我专攻代码之前,我想谈谈我尝试做的事.您可能记得,SuperGraph 让您从函数列表中进行选择.我希望能够在具体的目录中 ...
- Assembly.Load动态加载程序集而不占用文件 z
方式一:占用文件的加载 Assembly assembly = Assembly.Load(path); 用上面的方法可以动态的加载到dll,但是用这种方法加载到的dll一直到程序运行结束都是占用的d ...
- 重温CLR(十七)程序集加载和反射
本章主要讨论在编译时对一个类型一无所知的情况下,如何在运行时发现类型的信息.创建类型的实例以及访问类型的成员.可利用本章讲述的内容创建动态可扩展应用程序. 反射使用的典型场景一般是由一家公司创建宿主应 ...
- 未能加载文件或程序集“XXXXXX”或它的某一个依赖项。试图加载格式不正确的程序。
在本机WIN7机器上的WebService部署到Win2008R2上发现错误 “/”应用程序中的服务器错误. 未能加载文件或程序集“XXXXXX”或它的某一个依赖项.试图加载格式不正确的程序. 说明: ...
- C#如何加载程序运行目录外的程序集
我们的应用程序部署的时候,目录结构一般不会只有运行程序的目录这一个,我们可能在运行目录下建子目录,也可能使用System32目录,也可能使用其它第三方的程序集..Net程序集 首先会在GAC中搜索相应 ...
随机推荐
- python中的map、reduce、filter、sorted函数
map.reduce.filter.sorted函数,这些函数都支持函数作为参数. map函数 map() 函数语法:map(function, iterable, ...) function -- ...
- log4j日志相对路径,Tomcat(第三方和Springboot内置)参数catalina.home和catalina.base的设置
关于Log4j日志相对路径的配置请看:log4j 产生的日志位置设置 和 catalina.home.catalina.base . 由于我们在Log4j的配置中引入了系统属性${catalina.b ...
- poj 1182 (扩展并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 58979 Accepted: 17247 Description ...
- Longest Valid Parentheses——仍然需要认真看看(动态规划)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Search for a Range——稍微升级版的二分查找
Given a sorted array of integers, find the starting and ending position of a given target value. You ...
- SEO页面标题Title的优化
我在一个月前改过页面标题(Title),随后表现是:百度网页快照4天不更新,Google正常.而我仅仅是改了两个词组而已.在建博初期,修改Title的最频繁的时期,下面卢松松就我经历的修改Title过 ...
- centos7.5安装seafile
1.配置yum源 [root@localhost yum.repos.d]# uname -r3.10.0-693.el7.x86_64 [root@localhost yum.repos.d]# c ...
- Java之IO流的关闭
1.在finally中关闭流: OutputStream out = null; try { out = new FileOutputStream(""); // ...操作流代码 ...
- java线程基本知识
如何去定义一个线程?(三种方式) 1.Thread:继承这个类,然后重写run方法:将业务逻辑或任务写到run方法中,然后调用start来启动线程: 2.Runnable: 实现这个接口, ...
- 运行python程序不显示cmd的方法
运行python程序的时候会在背景显示一个cmd,要想不显示其实很简单(虽然是我找了1个小时...才了解的基本知识) 方法1:pythonw xxx.py 方法2:将.py改成.pyw (这个其实就是 ...