手动添加的assembly和自动加载的有什么区别

时间:2022-01-20 19:25:53
我编写了一个dll,包含一个class A,在另外一个工程中引用了这个dll,并使用了这个class,运行时正常,代码大概如下
A a=new A();
然后我再利用Assembly手动加载这个dll,
Assembly.LoadFrom("dll path");
A a =new A();
编译时由于引用了此dll,正常通过。
运行时我将此dll移动到指定路径,想通过Assembly加载,加载成功,不过运行创建A对象就出错。
这说明了手动加载的dll与自动加载的是有区别的,请问有没有人能解释一下他们的区别是什么?
还有,能不能手动加载后像自动加载的那样运行?应该怎么做?
谢谢各位~~~

12 个解决方案

#1


一个早期绑定  一个晚期绑定  
晚期绑定就不能A a =new A();这样去写
应该用反射去取A的信息

#2


我没写清楚,这些我知道,我想知道的不是使用上的区别,我找了内存中加载的dll,两种加载方式都把dll加载到内存,而且证据相同,我找不出他们的区别,可是为什么第二种情况就会出错呢?
各位高手,如果可以的话请针对这点进行分析一下,他们本质上的区别是什么呢?谢谢

#3


"运行时我将此dll移动到指定路径,想通过Assembly加载,加载成功,不过运行创建A对象就出错" ---- 没太弄明白你的意思,如果没有在项目中引用,写A a = new A()肯定是编译通不过的。

#4


Assembly.LoadFrom("dll path");
A a =new A();

---

肯定是你手动加入的引用没有把它删除,否则编译是通不过的。

Assembly a = Assembly.LoadFrom("dll path");
Type t = a.GetType("A");
A a = (A)Activator.CreateInstance(t)

#5


得把A定义成接口IA
IA a = (IA)Activator.CreateInstance(...);

要不删除了引用就编译出错了.

#6


得把A定义成接口IA
IA a = (IA)Activator.CreateInstance(...);

要不删除了引用就编译出错了.

---

对对对,倒底了这个了

#7


看不懂!都是大哥级的人物 , 学习中

#8


如果不是添加引用,而是代码里加载Assembly,就算加载成功了,A a =new A();它也不认识.
要用反射,方法楼上都说了,编译出错是因为这个类型A在你调用的程序中没有,换成IA也一样,都要在调用的程序中定义了才行,得是完全一样的.不过如果只是引用类型A,用反射干嘛.
归根结底,对于A a =new A();你在代码里加载Assembly是做无用功.

#9


首先谢谢各位的回答。
我清楚A myA = new A()是需要编译是类型确定的,所以我在编译时加上了dll引用,为的就是绕过这个问题,此时已经确定了编译可以通过了。
现在有两种加载dll方式:
1、运行时调用A myA = new A();此时会自动加载dll到内存中,而如果没有运行这语句dll是不会自动加载的。
2、用Assembly加载。此时我运行前先将dll移动到别的位置上,预防它自动被加载。加载到内存后再用A myA = new A();创建对象。
我分别使用两种方法加载了dll比较了他们的名称,并没有任何不同,它们都是这个dll在内存中的镜像,但是使用第二种方法加载后,调用A myA = new A();就会出错,这里说明了两者在内存中实际是不同的。
我想了解清楚,为什么会有这个不同呢?它们之间本质区别在哪里呢?
先谢谢各位的再次回答,可能的话请针对此问题继续讨论,在此敬礼!

#10


up

#11



添加一个程序集A的引用后,当前程序集会把A的信息加入这个程序集的元数据清单,所以你使用A myA = new A()是没问题,因为它可以根据外部程序集的引用找到程序集A。

Assembly是用来动态加载程序集的,也就是在运行时加载了一个程序集A,那么对其它程序集来说,A不可见的,它们对A的信息一无所知,那么A myA = new A();就会出错,只用使用Activator利用反射创建A的实例,当然先要把A抽象成一个接口。

不管用什么方法,加载进内存后,它们应该是没有区别的

#12


本质区别在于编译器(前期绑定)找不到你的类A。如果你在第二种方式把对A的引用(也就是你的自动加载)删掉的话,你编译能通过吗?
avisnet(第十维度) 是正确的。

#1


一个早期绑定  一个晚期绑定  
晚期绑定就不能A a =new A();这样去写
应该用反射去取A的信息

#2


我没写清楚,这些我知道,我想知道的不是使用上的区别,我找了内存中加载的dll,两种加载方式都把dll加载到内存,而且证据相同,我找不出他们的区别,可是为什么第二种情况就会出错呢?
各位高手,如果可以的话请针对这点进行分析一下,他们本质上的区别是什么呢?谢谢

#3


"运行时我将此dll移动到指定路径,想通过Assembly加载,加载成功,不过运行创建A对象就出错" ---- 没太弄明白你的意思,如果没有在项目中引用,写A a = new A()肯定是编译通不过的。

#4


Assembly.LoadFrom("dll path");
A a =new A();

---

肯定是你手动加入的引用没有把它删除,否则编译是通不过的。

Assembly a = Assembly.LoadFrom("dll path");
Type t = a.GetType("A");
A a = (A)Activator.CreateInstance(t)

#5


得把A定义成接口IA
IA a = (IA)Activator.CreateInstance(...);

要不删除了引用就编译出错了.

#6


得把A定义成接口IA
IA a = (IA)Activator.CreateInstance(...);

要不删除了引用就编译出错了.

---

对对对,倒底了这个了

#7


看不懂!都是大哥级的人物 , 学习中

#8


如果不是添加引用,而是代码里加载Assembly,就算加载成功了,A a =new A();它也不认识.
要用反射,方法楼上都说了,编译出错是因为这个类型A在你调用的程序中没有,换成IA也一样,都要在调用的程序中定义了才行,得是完全一样的.不过如果只是引用类型A,用反射干嘛.
归根结底,对于A a =new A();你在代码里加载Assembly是做无用功.

#9


首先谢谢各位的回答。
我清楚A myA = new A()是需要编译是类型确定的,所以我在编译时加上了dll引用,为的就是绕过这个问题,此时已经确定了编译可以通过了。
现在有两种加载dll方式:
1、运行时调用A myA = new A();此时会自动加载dll到内存中,而如果没有运行这语句dll是不会自动加载的。
2、用Assembly加载。此时我运行前先将dll移动到别的位置上,预防它自动被加载。加载到内存后再用A myA = new A();创建对象。
我分别使用两种方法加载了dll比较了他们的名称,并没有任何不同,它们都是这个dll在内存中的镜像,但是使用第二种方法加载后,调用A myA = new A();就会出错,这里说明了两者在内存中实际是不同的。
我想了解清楚,为什么会有这个不同呢?它们之间本质区别在哪里呢?
先谢谢各位的再次回答,可能的话请针对此问题继续讨论,在此敬礼!

#10


up

#11



添加一个程序集A的引用后,当前程序集会把A的信息加入这个程序集的元数据清单,所以你使用A myA = new A()是没问题,因为它可以根据外部程序集的引用找到程序集A。

Assembly是用来动态加载程序集的,也就是在运行时加载了一个程序集A,那么对其它程序集来说,A不可见的,它们对A的信息一无所知,那么A myA = new A();就会出错,只用使用Activator利用反射创建A的实例,当然先要把A抽象成一个接口。

不管用什么方法,加载进内存后,它们应该是没有区别的

#12


本质区别在于编译器(前期绑定)找不到你的类A。如果你在第二种方式把对A的引用(也就是你的自动加载)删掉的话,你编译能通过吗?
avisnet(第十维度) 是正确的。