先决条件
Common
IModule
程序集
Main
项目,引用Common
Implementor
项目,引用Common
,但未引用Main
构建完所有内容后,Common.dll
和Main
中都会显示Implementor
。现在Main
项目尝试在运行时加载实现IModule
的类。到目前为止我能做到的:
Dim asm = Assembly.LoadFrom(asmFile)
For Each asmType in asm.GetExportedTypes()
If asmType.IsClass AndAlso
asmType.GetInterfaces().Any(Function(i) i.Name = GetType(IModule).Name) Then
Dim handle = AppDomain.CurrentDomain.CreateInstanceFrom(asmFile, asmType.FullName)
Dim inst = CType(handle.Unwrap(), IModule) ' EXCEPTION
End If
Next
所以我可以加载Implementor
程序集并找到实现IModule
的类型。但是我无法创建它的实例,以便我可以将它投射到我的本地IModule
。这有可能吗?
解决方法
我找到了一种解决方法 - 在Implementor
项目中,点击对Common
的引用并清除"复制本地"旗。然后我甚至可以使用更简单的代码,比如IsAssignableFrom()
。但这是唯一的方法吗?如果我从第三方获取DLL,IModule
被编译到其中会怎么样?
答案 0 :(得分:0)
修改强>:
Assembly.LoadFrom
在目录树中加载第一个找到的匹配程序集(通过所谓的Probing Path)。因此,如果您拥有Common
DLLin文件夹A,并且更新的Common
DLL位于文件夹A \ B中,则会获取文件夹A中的DLL(如果两个dll具有相同的名称)。
来自MSDN:
load-from上下文允许从不是路径加载程序集 包含在探测中,但允许依赖于该路径 找到并加载,因为路径信息由。维护 上下文。
LoadFrom方法具有以下缺点。考虑使用 改为加载。
If an assembly with the same identity is already loaded, LoadFrom returns the loaded assembly even if a different path was specified. If an assembly is loaded with LoadFrom, and later an assembly in the load context attempts to load the same assembly by display name,
加载尝试失败。当程序集发生时,可能会发生这种情况 解串行化。
If an assembly is loaded with LoadFrom, and the probing path includes an assembly with the same identity but a different location,
InvalidCastException,MissingMethodException或其他意外情况 行为可能会发生。
原始答案:
使用Activator.CreateInstance
创建对象,使用typeof
检查它是否实现了接口:
Dim a As assembly = Assembly.LoadFrom(asmFile)
Dim concreteModule As IModule = Nothing
For each type In a.GetExportedTypes().Where(Function(x) x.IsClass)
Dim o = Activator.CreateInstance(type)
If TypeOf o Is IModule
concreteModule = DirectCast(o, IModule)
Exit For
End If
Next
备注:
您写道:But I can't create an instance of it such that I can cast it to my local IModule
。
具体对象必须实现您投射到的接口。我不知道我是否理解正确但是从第三方dll中的接口IModule
转换到本地dll中的不同接口IModule*
将无效(除非您的本地接口实现了另一个)