关于c#:通过动态程序集加载获取派生类?

Get derived class via dynamic Assembly loading?

我有两个DLL,一个带有接口,另一个实际使用接口。我可以使用反射调用第二个dll,但我想知道是否可以使用接口获得更多关于它的信息。

我有点像…

1
2
3
4
5
6
7
// the interface dll
namespace Mynamespace{
  public interface Interface1
  {
    int Add( int a, int b);
  }
}

同一个dll中的另一个接口…请注意,它是从第一个派生出来的。

1
2
3
4
5
6
namespace Mynamespace{
  public interface Interface2 : Interface1
  {
    int Sub( int a, int b);
  }
}

然后我调用一个使用反射的方法

1
2
3
4
5
6
7
8
9
10
11
// get the 2 interfaces
var asm = Assembly.LoadFile( dllInterfacePath);
var type1 = asm.GetType("Mynamespace.Interface1");
var type2 = asm.GetType("Mynamespace.Interface2");

// get the main class
var asmDll = Assembly.LoadFile( dllPath);
var type = asmDll.GetType("MyMS.SomeClass");

// create an instance
var instance = Activator.CreateInstance( type, null );

现在我的问题是,我如何判断创建的实例是从Interface2还是Interface1派生出来的,我可以查找方法"sub(…)",如果它不存在,那么我知道它是Interface1类型。

但我想知道是否有更好的功能来动态地实现这一点?

我不能用

1
typeof(Interface1).IsAssignableFrom(typeof(MyMS.SomeClass));

因为Interface1MyMS.SomeClass都是动态加载的,并且没有在项目中引用。


您不必使用typeof来进行类型引用,反射API对于动态加载的类型也能很好地工作。

Sorry, but it does not work. typeof(Interface1).IsAssignableFrom(typeof(MyMS.SomeClass)); or type.IsAssignableFrom(type1); does not work

它确实有效,但是通过调用LoadFile您基本上要加载同一个接口程序集两次,因此不可能在实现它的类上引用同一个接口类型:

https://blogs.msdn.microsoft.com/suzbook/2003/09/19/loadfile-vs-loadfrom/

LoadFrom甚至ReflectionOnlyLoadFrom替换LoadFile

我刚刚重新创建了您的场景,我有一个带有接口的程序集和另一个带有实现的程序集。

1
2
3
4
5
6
7
8
9
10
11
Assembly interfaceLib      = Assembly.ReflectionOnlyLoadFrom("InterfaceLib.dll" );
Assembly implementationLib = Assembly.ReflectionOnlyLoadFrom("ImplementationLib.dll" );

var i = interfaceLib.GetType("InterfaceLib.Interface1" );
var t = implementationLib.GetType("ImplementationLib.Class1" );

var b = i.IsAssignableFrom( t );

Console.WriteLine( b );

// prints"true"

如果我切换到LoadFile,我会得到false