在开始本文以前先提两个疑问:spa
1、一个.Net程序依赖不少的dll,那个他们是在应用程序启动的时候所有把所依赖的动态库所有都加载到应用程序域中的呢仍是有选择的加载呢?3d
2、当应用程序已经启动后咱们动态加载程序集的话,那么该程序集所依赖的程序集是所有加载仍是按需加载呢?blog
1、分析第一个问题:io
建立三个工程ConsoleApplication1是控制台工程,依赖于类库ClassLibrary1,而ClassLibrary1又依赖于ClassLibrary2工程。 引用
实验1:ConsoleApplication1引用了ClassLibrary1并经过using ClassLibrary1 可是并无调用ClassLibrary1中的成员,打印出应用程序域中加载的程序集,并无把ClassLibrary1加载进来 反射
实验2:把实验1中的注释去掉调用ClassLibrary1中Class1.Print()方法,并把断点设置在该方法上,阻止方法执行,打印出应用程序域中加载的程序集,发现ClassLibrary1已经加载j进来了,而Class1引用了CassLibrary2,但CassLibrary2并无加载程序
进入Class1.Print()方法,打印出应用程序域中加载的程序集,发现ClassLibrary2已经加载j进来了方法
实验1、实验2证实应用程序启动后clr加载dll是按需加载的,当进入一个方法的时候,即便没有执行该方法内的任何代码,都会收集该方法内部用到的全部类型,并加载相应类型所在的dll。im
2、分析第二个问题:动态加载
仍是上面的三个工程,改变依赖关系。ConsoleApplication1不依赖于ClassLibrary1和ClassLibrary2,而ClassLibrary1 依然依赖ClassLibrary2
ConsoleApplication1要经过Assembly.LoadFrom加载ClassLibrary1观察域中的程序集。
实验1:ConsoleApplication1项目经过Assembly.LoadFrom的方式手动加载程序集ClassLibrary1.dll,并无执行其中的代码,打印出应用程序域中加载的程序集,发现ClassLibrary1已经加载j进来了,但ClassLibrary1所引用的ClassLibrary2并无加载进来
继续执行经过反射调用Class.Printff方法,打印出应用程序域中加载的程序集,发现ClassLibrary2已经加载j进来了
因而可知动态加载程序集,在没有调用程序集内部成员的状况下 只加载自己,当调用内部成员的时候加载规则和clr自动加载dll是同样的。
结论:clr加载程序集是按需加载的,当用到的时候才会把其加载到应用程序域中。