使用反射在同一程序集的不同版本中使用类对象
我需要加载不同版本的程序集(我的应用程序中已经有同名的程序集)。
我能够加载程序集并加载需要使用反射调用的方法,但是当我通过将类对象作为参数传递来调用该方法时,出现了类对象无法转换为参数参数类型的异常。
示例代码 -
Assembly myAssembly = Assembly.LoadFrom("Assembly Path for assembly with different version");
object classObject = myAssembly.CreateInstance("ClassName");
Type classType = myAssembly.GetType("ClassName");
MethodInfo myMethod = classType.GetMethod("MyMethod", BindingFlags.Instance);
// Creating an object of class in the latest assembly and need to pass this
// to method in assembly with different version.
ClassInBothVesions parameter = new ClassInBothVesions();
myMethod.Invoke(classObject, new object[] { parameter });
这里参数是我在程序集中拥有的类的对象,但由于参数类是在当前版本的程序集中创建的。当我尝试将它传递给以前的程序集的方法时,我得到一个异常,它无法转换。
我怎样才能做到这一点?如果我需要在这里提供更多信息,请告诉我。提前致谢。
I have a requirement of loading assembly of different version(I already have the assembly with same name in my application).
I was able to load the assembly and load the method i need to invoke using reflection but when i go to invoke the method by passing my class object as argument, i got the exception that class object cannot be converted to the type of argument parameter.
Sample Code -
Assembly myAssembly = Assembly.LoadFrom("Assembly Path for assembly with different version");
object classObject = myAssembly.CreateInstance("ClassName");
Type classType = myAssembly.GetType("ClassName");
MethodInfo myMethod = classType.GetMethod("MyMethod", BindingFlags.Instance);
// Creating an object of class in the latest assembly and need to pass this
// to method in assembly with different version.
ClassInBothVesions parameter = new ClassInBothVesions();
myMethod.Invoke(classObject, new object[] { parameter });
Here parameter is an object of a class which i have in assembly but since parameter class is created in the assembly of the current version. And when i try to pass it to the method of previous assembly, i got an exception that it cannot be converted.
How can i achieve this? Let me know in case if i need to put on some more information here. Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该查看托管可扩展性框架 (MEF)。它使您更轻松地做您想做的事情,并使您不必担心 AppDomain 和不同的程序集。
编辑:
如果您只想使用反射来实现您想要的目的,则应用程序中需要灵活的对象模型。这种方法的基本原理就是 MEF 在幕后所做的事情。您真正能够做到这一点的地方是来自 .Net 远程处理,所以我建议您仔细阅读。
您需要什么:
(程序集 A)中的应用程序。
使用旧类代码进行汇编(程序集 C)。
一个远程加载程序类,它将充当第二个 AppDomain 的代理/远程。
一个代理类,它将代表旧版本类的实例。
程序集 B 将包含您的代理类和远程加载程序。
您可以尝试以下操作:
从程序集 A 加载应用程序。
创建新的 AppDomain 实例。
在程序集 B 的新 AppDomain 中实例化“Remote Loader”类的实例。
a.这将导致程序集 B 被加载到 AppDomain 中。
从“远程加载程序”中加载程序集 C 并实例化旧类,然后将代理类的实例传回原始 AppDomain。
现在希望您可以修改您的方法以接受代理和新类版本都可以实现的更通用的对象版本(可能是接口?)。
You should check out the Managed Extensibility Framework (MEF). It makes doing what you want to do much easier and abstracts you away from having to worry about AppDomains and different assemblies.
Edit:
If you wish to use reflection only to achieve what you want, it'll require a flexible object model within your application. The basics of this approach is what MEF kind of does underneath the hood. Where you really get the power to do this is from .Net remoting, so I'd suggest you read up on that.
What you'll need:
Your application in (assembly A).
Assembly with old class code (assembly C).
A Remote Loader class that will act as your proxy/remote to the second AppDomain.
A proxy class that will represent an instance of the old version of a class.
Assembly B which will contain your proxy class and your remote loader.
Here's what you could try:
Load application from assembly A.
Create new AppDomain instance.
Instantiate an instance of your "Remote Loader" class in the new AppDomain from assembly B.
a. This will cause assembly B to be loaded into the AppDomain.
From your "Remote Loader", load assembly C and instantiate your old class then pass back an instance of the proxy class to the original AppDomain.
Now hopefully you can modify your methods to accept a more generic version of the object (possibly an interface?) that the proxy and your new class version can both implement.