【VB】動的にクラスをロードして、文字列でメソッドを指定して実行する
@IT - 文字列で指定したクラスのインスタンスを作成するには?
@IT - 文字列で指定したメソッドを呼び出すには?
@IT - メソッドやプロパティの有無を確認して呼び出すには?
この記事を参考に、動的にクラスをロードして、文字列でメソッドを指定して実行する処理を書いてみる。
Loader.vb
Imports System.Reflection ''' <summary> ''' クラスロード制御クラス ''' </summary> ''' <remarks>クラスの動的ロードに関する制御を行います。</remarks> Public Class Loader ''' <summary> ''' コンストラクタ ''' </summary> ''' <remarks>外部からのインスタンス化は行えません。</remarks> Private Sub New() End Sub ''' <summary> ''' クラスロード処理 ''' </summary> ''' <param name="className">クラス名</param> ''' <param name="filePath">クラスを有するDLLパス</param> ''' <returns> ''' 成功時:Typeオブジェクト<br /> ''' 失敗時:Nothing ''' </returns> ''' <remarks>指定されたクラスのロード処理を行います。</remarks> Public Shared Function loadClass(ByVal className As String, Optional ByVal filePath As String = Nothing) As Type Dim classType As Type classType = Type.GetType(className) 'アセンブリにロードされていない場合はDLLをロードする If classType Is Nothing Then If System.IO.File.Exists(filePath) = False Then Return classType End If Dim asm As Assembly = Assembly.LoadFrom(filePath) classType = asm.GetType(className) If classType Is Nothing Then asm = Nothing End If End If Return classType End Function End Class
MyClass1.vb
Public Class MyClass1 Public Sub testMethod1() System.Windows.Forms.MessageBox.Show("DLLのtestMethod()が呼び出されました") End Sub End Class
Window1.vb
Public Class Window1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'クラスのロード Dim classType As Type = Loader.loadClass("ClassLibrary1.MyClass1", System.IO.Directory.GetCurrentDirectory() & "\..\..\..\ClassLibrary1\bin\Debug\ClassLibrary1.dll") If classType Is Nothing Then Return End If Dim classInstance As Object = Nothing Try '通常のインスタンス化 classInstance = Activator.CreateInstance(classType) '指定メソッド名の実行 Dim mi As Reflection.MethodInfo = (classInstance.GetType()).GetMethod("testMethod") mi.Invoke(classInstance, Nothing) Catch ex As InvalidCastException 'キャスト失敗 classInstance = Nothing Catch ex As MissingMemberException '引数なしコンストラクタの存在がない classInstance = Nothing End Try End Sub End Class
loadClass()の第一引数には、名前空間を含むクラス名を指定すれば良い。
第二引数はDLLのフルパス。
そもそもDLLが既にロードされている場合は、Type.GetType("名前空間.クラス名, アセンブリ名")という指定になるので、使い方間違ってんな俺。
インターフェースを実装しているかどうかをチェックしたいならば、Typeクラス内のGetInterface()で取得できるかどうかを検証すればいいようだ。
ただ、どうも散々調べてみたけど、『特定のクラスを継承しているかどうか』を検証する方法が見つからなかった・・・。
ご存知の方は是非pleeeeeeeeeeez!!