プラグイン 基本のキ VB2005

VB Tips And Sample(HOME)(VB.NET Sample インデックス)

プラグイン 基本のキ VB2005でやってみた


プラグイン機能の基本的な考え方。
①インターファイスだけのDLL(クラスの設計図DLLを作成)=これがプラグイン(外部DLL)の設計図となる。
②プラグイン(外部DLL)の中身をインターフェイスに従って記述・実装する。
③プラグイン(外部DLL)を使えるEXE・アプリケーションを作成する。
外部DLLを追加・変更することでEXE・アプリケーション機能を変更することが出来るメリットが生まれる。
インターフェイスについて解らなければここを参考にして下さい。

サンプル概要
出来るだけ簡単なサンプルと言うことで、[メッセージボックスを出す、数値を100倍にするだけの機能]を持ったプラグインを作成してみた。
プラグインにしておけば、[メッセージボックスを出す、数値を5000倍にする機能]を追加することも変更することも出来るようになる。

参考にさせていただいたサイト
とっても詳しく書かれています。↓
DOBON.NET のプラグイン機能を持つアプリケーションを作成する
.NETによるプラグイン機能を持つテキストエディタの作成


①インターファイスだけのDLL(クラスの設計図DLLを作成)=これがプラグイン(外部DLL)の設計図のDLLとなる。

VB2005の新規プロジェクトで「クラスライブラリ」を作成する。
プロジェクト名は「MyInterface」。
クラスのClass1のファイルが開くので、下記のソースをコピペ。全角スペース等は適当に修正。



Imports System

Public Interface MyInterface
    'これがプラグインの設計図となる
    'このインターフェイスを使用して、つまり窓口にして、
    '色々な機能=(VBMsg、mCalcu、の中身を実装したクラス)をとっかえひっかえ使用できるようになる。
    Sub VBMsg(ByVal moji As String)
    Function mCalcu(ByVal x As Integer) As Integer

End Interface


ビルドしてdllを作成。
binフォルダの中に「MyInterface.dll」が出来上がる。


②プラグイン(外部DLL)の中身をインターフェイスに従って記述・実装する。

VB2005の新規プロジェクトで「クラスライブラリ」を作成する。
プロジェクト名は「MyNewCaluc」。
参照設定で、先ほど作った「MyInterface.dll」を参照。
参照設定で、System.Windows.Formsを参照。
クラスのClass1のファイルが開くので、下記のソースをコピペ。全角スペース等は適当に修正。


Imports System
Imports System.Windows.Forms 'MessageBoxのため 参照設定をする



Public Class Class1
    Implements MyInterface.MyInterface

    Public Sub VBMsg(ByVal moji As String) Implements MyInterface.MyInterface.VBMsg
        MessageBox.Show(moji & "単に100倍する計算", "新機能でもないけど新機能です。", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    Public Function mCalcu(ByVal x As Integer) As Integer Implements MyInterface.MyInterface.mCalcu
        '単に100倍する計算
        Return x * 100
    End Function
End Class


ビルドしてdllを作成。
binフォルダの中に「MyNewCaluc.dll」が出来上がる。


③プラグイン(外部DLL)を使えるEXE・アプリケーションを作成する。
VB2005の新規プロジェクトで「Windows アプリケーション」を作成する。
プロジェクト名は「MyNewApli」。
フォームに
ボタン2つ。
テキストボックス1つ。
を張り付ける。
参照設定で、一番最初に作った「MyInterface.dll」を参照。
プラグイン「MyNewCaluc.dll」の場所は「Public Class PluginInfo」の記述により適切に変更する。

フォームに下記のコードを記入。


Public Class Form1

↓ここはリフレクションという機能を使用。
PluginInfo.FindPlugins()などは、DOBON.NETさんの「Public Class PluginInfo」のソースを参考にさせていただきました。コピペでも動くはず。
    'インストールされているプラグインを調べる
    Public p As MyNewApli.PluginInfo() = PluginInfo.FindPlugins()
    'プラグインクラスのインスタンスを作成する
    Public plugin(0) As MyInterface.MyInterface

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        MessageBox.Show("答え" & plugin(0).mCalcu(Me.TextBox1.Text).ToString, "プラグイン1", MessageBoxButtons.OK)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim i As Integer
        For i = 0 To plugin.Length - 1
            plugin(i) = p(i).CreateInstance()
        Next i

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        plugin(0).VBMsg("成功?")
    End Sub
    
End Class




③ リフレクションを分かりやすくしたもの
プラグイン(外部DLL)を使えるEXE・アプリケーションを作成する。

極力単純化していけば、このようになります。

Public Class Form1

    'MS→System.Reflection 名前空間には、読み込まれた型、メソッド、およびフィールドのマネージ ビューを提供し、
    '動的に型を作成したり呼び出すことができるようにするクラスとインターフェイスが含まれています。 
    'アセンブリを読み込む
    '↓ここを動的に作成実現しているのがDOBONさんのサンプルとなる
    Public asm As System.Reflection.Assembly = System.Reflection.Assembly.LoadFrom(Application.StartupPath & "\plugins\MyNewCaluc.dll")

    Public ob As MyInterface.MyInterface 'インターフェイス(クラスの設計図)の型を作成

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        MessageBox.Show("答え" & ob.mCalcu(CInt(Me.TextBox1.Text)).ToString, "プラグイン1", MessageBoxButtons.OK)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'Reflection機能! この型のインスタンスを作成します。  
        'ob = CType(asm.CreateInstance("MyNewCaluc.Class1"), MyInterface.MyInterface)

        Debug.WriteLine(asm.FullName.ToString)

        '型の名前を動的に取得するためには? 
        Dim ty As Type
        For Each ty In asm.GetTypes() 'GetTypes()=MS→このアセンブリで定義されているすべての型のオブジェクトを格納している Type 型の配列。を返す
            'アセンブリ内のすべての型について、
            'インターフェイス(クラスの設計図)を持っているか調査
            Debug.WriteLine(ty.FullName.ToString) 'FullName=MS→Type の名前空間を含み、アセンブリを含まない、Type の完全修飾名を取得します。 
            If ty.GetInterface("MyInterface.MyInterface") Is Nothing = False Then
                'Reflection機能! この型のインスタンスを作成します。
                ob = CType(asm.CreateInstance(ty.FullName.ToString), MyInterface.MyInterface)
            End If
        Next

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ob.VBMsg("成功?")
    End Sub

End Class



VB Tips And Sample(HOME)