C#, ロジック
- リフレクション
リフレクションによりDLLの中から指定クラスを継承しているクラスを探し出し、インスタンス化しています。
何に使うのかが難しいところですが、リフレクションは「Word」、「Internet Explorer」、「Eclipse」などのプラグイン対応のソフトウェアを作るときに絶大な威力を発揮します。例えば、メインモジュールを開発する人が1人と、不特定多数のプラグイン開発者がいたとします。メインモジュール開発者はプラグインのスーパークラスとなる抽象クラスを開発し、プラグイン開発者にDLLで配布します。プラグイン開発者はそのクラスを継承し、プラグインの実装を追加してDLLとして組み込みます(隣に置くだけ)。メインモジュールはリフレクションを使用してスーパークラスを継承するクラスをプラグインDLLから検索し、プラグイン内の具象クラスをインスタンス化します。メインモジュールはプラグインの中身は知り得ませんが、インターフェイスは全て知っているのでプラグインが公開しているインターフェイスはメインモジュールから呼び出せるということです。この仕組みによって、メインモジュールの変更なしに誰もがプラグインを開発できるということになります。
WinAPIの時代はLoadLibrary,FreeLibraryにより、同様の機能が実装されていました。リフレクションはLoadLibraryに値するものですが、FreeLibraryに値するものは.NETにはありません。
下の例は.NET Frameworkに定義されている「テキストボックス」を単純にデザイナで貼り付けるのではなく、System.Windows.Forms.dllをロードして動的にインスタンス化し、画面に貼り付けています。このコード自体にあまり意味は無いですが、テキストボックスのサブクラスを不特定多数の人に作ってもらうような場合に意味をもちます(そのような場面は無いと思いますが)。
public partial class FormRefrection : Form
{
public FormRefrection()
{
InitializeComponent();
}
private void FormRefrection_Load( object sender, EventArgs e )
{
System.Reflection.AssemblyName assemblyName = new System.Reflection.AssemblyName();
assemblyName.CodeBase =
@"C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll";
// DLLロード
System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load( assemblyName );
// DLLの中からテキストボックスクラス検索
foreach( Type type in assembly.GetTypes() )
{
if( type.IsSubclassOf( typeof( TextBox ) ) == false )
{
continue;
}
// 見つけた。インスタンス化。
TextBox textBox = Activator.CreateInstance( type ) as TextBox;
// 画面に貼り付ける。
this.Controls.Add( textBox );
break;
}
}
}