最近のトラックバック

2020年7月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

« C#で共有フォルダ作成/削除 | トップページ | Windows 7 RTMを使ってみた »

C#でプラグイン実装

C#でプラグインを実装するサンプルを紹介する。


■プラグインとは
ここに来る人ならプラグインがどんなものか知っていると思うが一応記述する。

  • アプリケーションソフトウェアの機能を拡張するために追加するプログラムの一種。
  • 誰でも差し替え可能になっているアプリケーションコードの一部分を、プラグインと呼ぶ。
  • プラグインを利用する者に開発者と同じコンパイラを用意させるのは現実的ではないので、プラグインの場合、ダイナミックリンクライブラリと呼ばれる機構を使って、アドレスを間接的に参照する事によりこの問題を回避する。

プラグイン - Wikipediaから抜粋。

というわけで、本サンプルでもDLLを利用しプラグインを実装する。
なお多く場合、C#ではインタフェースやベースクラスを利用したポリモーフィズム(多態性)を利用することになる。
デザインパターンでいえばStrategy パターンかな?

■プロジェクト構成
本サンプルは以下の4プロジェクト構成となっている。
DLL/EXEファイル 概要 クラス/インタフェース プロジェクト名 プロジェクト参照
PluginBaseLib.dll プラグイン仕様となるインタフェース/ベースクラスを含むクラスライブラリ。 PluginInterface
PluginBaseClass
PluginBaseLib -
PluginDerivedLib1.dll プラグインその1。
PluginInterfaceまたはPluginBaseClassの派生クラスを持つクラスライブラリ。
PluginDerivedInterface1
PluginDerivedClass1
PluginDerivedLib1 PluginBaseLib
PluginDerivedLib2.dll プラグインその2。
PluginInterfaceまたはPluginBaseClassの派生クラスを持つクラスライブラリ。
PluginDerivedInterface2
PluginDerivedClass2
PluginDerivedLib2 PluginBaseLib
UsePlginConsole.exe 上記プラグインを利用するコンソールアプリケーション。 UsePlugin
Program
UsePlginConsole PluginBaseLib



■フォルダ構成
プラグインDLLは所定の場所に置く必要がある。
実行ファイルを起点とした相対パスでプラグイン専用フォルダを作成する。

アプリケーションフォルダ
│  PluginBaseLib.dll
│  UsePlginConsole.exe
│  
└─Plugin
        PluginDerivedLib1.dll
        PluginDerivedLib2.dll



■アプリケーション構成

・PluginDerivedInterface1クラス・PluginDerivedInterface2クラスはPluginInterfaceインタフェースを継承。
・PluginDerivedClass1クラス・PluginDerivedClass2クラスはPluginBaseClassクラスを継承。
・UsePluginクラスのfnLoadPluginInstance()メソッドは指定フォルダからPluginDerivedLib1.dllとPluginDerivedLib2.dllをロード、 PluginInterfaceまたはPluginBaseClassを継承しているクラスを探し、インスタンス化したのち、継承元のリストに登録する。
・UsePluginクラスのfnUsePluginProc()メソッドはリスト登録されたPluginInterfaceまたはPluginBaseClassの派生クラスをShow()メソッドを介して、派生先でオーバライドされたShow()メソッドを実行。


■プラグイン仕様となるインタフェース/ベースクラスを含むクラスライブラリ。(Plugin.cs - PluginBaseLib.dll)
■プラグインその1。(PluginDerived1.cs - PluginDerivedLib1.dll)
■プラグインその2。(PluginDerived2.cs - PluginDerivedLib2.dll)
■上記プラグインを利用するコンソールアプリケーション:プラグイン利用クラス。(UsePlugin.cs - UsePlginConsole.exe)
■上記プラグインを利用するコンソールアプリケーション:Programクラス。(Program.cs - UsePlginConsole.exe)
■実行結果


※注意
この考察は記事を書いた時点での記述者の考えです。
「全てのケースに対応」とか「一般的な考え」とか「ベストプラクティス」とかではありませんし、いうつもりもありません。
話半分ぐらいで読んでいただけると非常に助かります。

■プラグインはどんな時に作る?
まず遊び心が必要です。
ついでに、
◆インタフェース/ベースクラスを抽出できるが、開発者サイドで全ての機能を用意できない(しない)場合。
◆処理拡張が必要で、かつインタフェース/ベースクラスを抽出できる場合。
◆画像・音楽・動画のように多種の既知・未知のファイルフォーマットを扱う場合。
◆一般公募や特典のオマケでゲームを拡張したい場合。
 ※アクションゲームの武器、カーレースで車種・パーツ拡張・格闘ゲームで追加キャラ等
◆ブラウザやオフィスソフトのようなアドオン機能を提供する場合。
◆既知・未知を含め複数デバイスをサポートするアプリケーションの場合。

■そもそもプラグインって必要?
ほとんどのアプリケーションでは不要です。

■プラグインはいつ構想・実装する?
開発初期から構想しておくほうが望ましい。。
初回リリースからプラグインを一般公開しなくても設計段階でインタフェース/ベースクラス抽出したほうがよい。
リリース後に必要に応じてプラグイン化も可能だが構造変更のインパクトが非常に大きい。

■仕様公開するのはインタフェース。それともベースクラス?
個人的にはベースクラスのほうがインタフェースよりも使い勝手がよいと思う。

<ベースクラスのメリット>
◆利用頻度の高いフィールド変数を事前に用意できる。
◆共通処理をメソッドとして提供しやすい。
◆デザインパターン「template method」やイベントが使いやすい。
◆提供側がバージョンアップ時の機能拡張がしやすい。

<ベースクラスのデメリット>
◆シンプルなインタフェースと違い処理を内包するため不具合が起こりやすい。
 →修正したモジュールの再配布率があがる。
  →修正モジュールの配布が非常に手間。
   →利用側が修正モジュールをテストをしてくれない。
    また不具合を利用したプラグインを作られると目も当てられない
◆多重継承ができないため、利用側の自由度が低くなる。






« C#で共有フォルダ作成/削除 | トップページ | Windows 7 RTMを使ってみた »

パソコン・インターネット」カテゴリの記事

C#サンプル」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: C#でプラグイン実装:

« C#で共有フォルダ作成/削除 | トップページ | Windows 7 RTMを使ってみた »

Google AdSense


  • ---

Amazon ウィジェット

  • ウィジェット

@niyo_naのツイート

無料ブログはココログ

Google Analytics