CreateInstance()は - 私はこの権利をやっていますか?
-
09-09-2019 - |
質問
私は、.NETでのプラグインシステムを一緒に入れしようとしている、と私はそれを正しくやっているかはわかりません。システムの基礎は、特定の基本クラスを継承する場合、特定のディレクトリ({APPPATH} /プラグイン/)プリコンパイル済みのDLLの束を持って、私は反射してそれぞれを介して見てみたい、と利用可能なすべてのクラスのことです(これはまた別のDLLで定義されているが、私は後でそれに行くよ)、その後、インスタンスは述べています。
でそのインスタンスを作成して、特定の機能を呼び出しますPublic Sub ScanPluginsInDirectory(ByVal Directory As String)
Dim Plugins As New IO.DirectoryInfo(Directory)
Dim Files As IO.FileInfo() = Plugins.GetFiles("*.dll")
Dim CryptType As Type = GetType(CryptPluginBase)
Dim PluginsData as List(Of LoadedPluginsInfo)
For Each DllFile As IO.FileInfo In Files
Try
Dim thisAsm As Assembly = Assembly.LoadFrom(DllFile.FullName)
Dim ClassDefs = thisAsm.GetTypes().Where(Function(type) CryptType.IsAssignableFrom(type))
For Each ClassDef As Type In ClassDefs
Dim A As Object
A = ClassDef.Assembly.CreateInstance(ClassDef.Name)
PluginsData.Add(New LoadedPluginsInfo(A.Plugin(), False))
Next
Catch ex As Exception
Continue For
End Try
Next
End Sub
私が持っている固有の問題は、私は、これはこれを行うには正しい方法ではわからない、です。う、A.Plugin()
が実際に存在し、ここで参照された構造とクラスは、バグのないあると仮定することができる場合、私は、仕事をやろうとしている方法?誰が助けるために、より多くのコードが必要になる場合、私はそれを投稿することができます。
解決
全体的な戦略は動作するはずです。 Assembly.LoadFromコールは、プロセスにターゲットアセンブリをロードします。そこからは、型検査を行い、その型のインスタンスを作成することが可能です。
私は、インスタンスを作成するための最も簡単で確実な方法は、Activator.CreateInstanceメソッドを使用することだと思います。
For Each def As Type in ClassDefs
Dim inst = Activator.CreateInstance(def)
PluginsData.Add(new LoadedPluginsInfo(inst.Plugin(), False))
Next
あなたの目標に応じて、別の提案がループに代わりにそれからtry / catchブロックを移動させることであろう。ループの外側にtry / catchブロックを持つことは、アセンブリ内の任意の型がエラーを持っていない場合、あなたはそのアセンブリからのすべての種類を破棄することを意味します。内部にそれを移動すると、あなたは、現在の行動はしかし、あなたの意図かもしれexpect.dとして動作しないだけの種類を破棄することができます。
他のヒント
これは私が前にいくつかのプロジェクトではこの種のものを使用してきた、動作するはずです。私は、特に離れて、それは同じ考えだったことから、コンストラクタを探し、それを呼び出したもののます。
しかし、あなたはあなたのための多くのものの世話をする MEF に、見たいかもしれませんプラグインアーキテクチャ(あなたはリリースバージョン用のビットを待って喜んでいる場合、それは今のところまだCTPです)。