InvokeMember无法找到我的功能

时间:2017-10-19 21:09:11

标签: .net vb.net dll

我已经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.

1 个答案:

答案 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,并且必须传递一个布尔值(TrueFalseargs参数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