我已经google了,找不到有效的答案,我正在编写一个程序,从文件夹中加载所有模块,然后将变量传递给它们,并在需要时调用它们。
在DLL中我有一些非常基本的代码
Public Class Class1
Public Function Sub getManifest(a As Boolean)
Return "test"
End Sub
End Class
在我的主程序中,我也有一些代码。
For Each item In My.Computer.FileSystem.GetFiles("modules")
Await Log(New LogMessage(LogSeverity.Info, "Init", " Loading module at " & item))
Dim DLL = Assembly.LoadFile(item)
For Each type As Type In DLL.GetExportedTypes()
Dim c = Activator.CreateInstance(type)
Dim moduleManifest As moduleManifest = _
type.InvokeMember( _
"getManifest", _
BindingFlags.NonPublic Or BindingFlags.Static Or BindingFlags.InvokeMethod, _
Nothing, Nothing, New Object() {})
Next
Next
但我总是得到一个
MissingMethodException: Method 'module.Class1.getManifest' cannot be found.
答案 0 :(得分:2)
您使用了错误的BindingFlags
。您的方法既不是NonPublic
也不是Static
(即VB术语中的Shared
)。
使用
Dim moduleManifest As moduleManifest = _
type.InvokeMember(
"getManifest",
BindingFlags.InvokeMethod Or BindingFlags.Public Or BindingFlags.Instance, _
Nothing, c, New Object() { True })
此外,其中一个参数必须是您要调用c
的对象getManifest
,并且必须传递一个布尔值(True
或False
) args
参数a
的{{1}}数组。
更好的方法是让类实现一个接口。这样您就可以简单地将对象强制转换为此接口并直接调用该方法(不使用getManifest
)。
实现此目的的最佳方法是为合同(接口)提供单独的库程序集(DLL)。然后,您的应用程序和加载的模块(让我们称之为加载项)都必须引用此合同程序集。
InvokeMember
让您的外部类实现此接口。然后你可以像这样调用这个方法
Public Interface IAddIn
Function Sub GetManifest(a As Boolean) As ModuleManifest
End Interface
此外,要么在合同程序集中声明类For Each type As Type In DLL.GetExportedTypes()
Dim addIn = TryCast(Activator.CreateInstance(type), IAddIn)
If addIn IsNot Nothing Then
Dim manifest As ModuleManifest = addIn.GetManifest(True)
...
End If
Next
,要么在那里声明ModuleManifest
接口,让函数返回IModuleManifest
。