跨越不同的程序集版本传递类对象

Roh*_*ats 3 c# reflection reflector assemblies reflection.emit

场景如下 -

  • 我有一个组件说'MyAssembly'.接口说'IMyInterface'在此程序集中定义.
  • 在同一个程序集中,我有一个类(MyClass),其中的方法定义如下:

public void MyMethod(IMyInterface object){}

  • 现在,在我的项目中,我创建了一个具有相同名称和确切属性的接口,这些接口由"MyAssembly"中的"IMyInterface"接口公开.
  • 我有一个扩展此接口的类(我在我的项目中创建的那个),我希望将该类的对象作为参数传递给使用反射的不同程序集中的方法"MyMethod".

问题是 -

  • 当我尝试使用反射调用方法时,我得到了"无法将对象转换为类型IMyInterface"的异常.

代码 -

Assembly myAssembly = Assembly.LoadFrom("MyAssembly");
object classObject = myAssembly.CreateInstance("MyClass");
Type classType = myAssembly.GetType("MyClass");
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.
ClassExtendingMyInterface obj= new ClassExtendingMyInterface ();

myMethod.Invoke(classObject, new object[] { obj});
Run Code Online (Sandbox Code Playgroud)

如果,我说得对,这是因为创建的对象是在不同的程序集中,并且该方法所期望的参数是它自己的程序集.

我想到的另一种方法是在类中创建我自己的动态方法,它将接受我的类的对象.

我试图通过Reflection.EmitRunSharp来google并动态创建自己的类.但是,我们只能在动态生成的程序集中使用它,但不能在现有程序集中创建动态方法或类.

我知道在运行时生成程序集并不是一个好方法.但我现在想不出任何事情.谢谢你的帮助.

Han*_*ant 6

你正在与一种名为"类型标识"的东西作斗争,这是一种非常重要的DLL地狱反措施.类型不仅由其名称空间名称和类型名称标识,还包括它来自的程序集的属性.具体是程序集显示名称,[AssemblyVersion],[AssemblyCulture],PublicKeyToken和(间接)ProcessorArchitecture.您可以使用Type.AssemblyQualifiedName属性查看"真实"类型名称.例如,System.String类是System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

这会阻止您伪造另一个程序集中的类型,除非您可以为该程序集提供完全相同的属性.简单地使用现有的程序集就容易多了,因为你只使用了一个接口,所以在你的情况下应该没问题.

值得注意的是,这个要求在.NET 4中有所放松.如果它们的名称和[Guid]匹配,则从COM类型库自动生成的类型是等效的.这有助于消除PIA并实施"嵌入互操作类型"功能.没有什么适用于您的情况.