最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
プラグインのロードはManager クラスのコンストラクタで行う。
手順としては、plugin フォルダの内部からアセンブリを探し、順にロードする。
そして、ロードしたアセンブリの中から、ISaver 実装型を検索するという流れだ。
では、コンストラクタを作る。
========== Manager.cpp ==========
#include "config.hpp"
#include "Manager.hpp"
#using "Loafer.ScreenSaver.dll"
using namespace System;
using namespace System::IO;
using namespace System::Reflection;
using namespace Loafer::ScreenSaver;
namespace Loafer {
namespace ScreenSaver {
namespace Host {
Manager::Manager() {
// プラグインフォルダを探索し
// プラグインを含むアセンブリを得る
String ^hostDir = Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location);
String ^pluginDir = Path::Combine(hostDir, "plugins");
array ^paths = Directory::GetFiles(pluginDir, "*.dll");
// アセンブリを読み込み、ISaver 実装型を得る
// ISaver の Type を用意
Type ^interfaceType = ISaver::typeid;
for each (String ^path in paths) {
// アセンブリを AppDomain にロード
Assembly ^plugin = Assembly::LoadFrom(path);
// 型を列挙
for each (Type ^type in plugin->GetTypes()) {
// public でかつ抽象ではなく、
// ISaver を実装し、デフォルトコンストラクタを持つ
if (type->IsPublic && !type->IsAbstract
&& interfaceType->IsAssignableFrom(type)
&& type->GetConstructor(Type::EmptyTypes) != nullptr) {
types.Add(type);
}
}
}
}
========== end of Manager.cpp ==========
「plugins」フォルダは、ホストのあるフォルダを基準とするため、
まず Assembly::GetExecutingAssembly() で、
自分自身(=ホスト)のアセンブリを取得し、
Location プロパティを参照して自分のパスを得る。
次いで、Path::GetDirectoryName() でフォルダ名を取りだし、
"plugins" を連結してサブディレクトリを得る。
そして、Directory::GetFiles() でアセンブリの配列を得る。
後は、プラグインの動的ロードの日記で書いたコードと同じ。
個々のアセンブリを読み込み、型を列挙するだけだ。
これで、ISaver を実装したクラスの Type 一覧が取得できるようになる。
コメント (0 件)