動的クラス登録
このページの目的
このページで説明する RtemplateEmbedder.cs を以下に示します。
RtemplateEmbedder.cs はアプリケーションへの動的なクラスの組み込みのテンプレートです。
目次:
ファイル名の "RtemplateEmbedder.cs" ですが、混乱を避ける意味でもファイル名を "RfakeEmbedder.cs" に変更した方が良いでしょう。
クラスの登録
クラスをアプリケーションに登録する唯一の方法は、RiceManager クラスの AddBuiltIn() メソッドを呼び出すことです。
public static void AddBuiltIn(string typename, PlainProtoTypeGetter pptg) |
一つ目の引数はクラス名です。
二つ目の引数は PlainProtoTypeGetter デリゲートです。
public delegate Rtype PlainProtoTypeGetter(); |
Cooker に静的に組み込まれているクラスについては、クラス名もデリゲートも既知ですので AddBuiltIn() メソッドを適切な引数で呼び出せます。例えば、Rbrowser クラスの登録は以下のようになっています。
RiceManager.AddBuiltIn(Rbrowser.TYPENAME, Rbrowser.InstanceGetter); |
動的に組み込まれるクラスは未知のクラスなのでクラス名もデリゲートも不明です。このままでは AddBuiltIn() メソッドを呼び出してクラスを登録することはできません。
しかしながら、RiceManager クラスには未知のクラスを登録するためのメソッドがあります。
public static void RegisterClasses(string directoryPath) |
Cooker は、これを利用して動的なクラス登録を行います。
動的なクラス登録には三つ規則があります。
1: 場所
動的組み込みクラスの .dll ファイルは実行ディレクトリの dlls サブディレクトリをルートにしたディレクトリ階層のどこかに置かれなければいけません。
2: 名前
概要で説明しています。
3: IEmbedPrototype インターフェース
動的組み込みクラスの .dll ファイルには IEmbedPrototype 派生クラスが必要です。
登録の手順
Cooker は起動時に RiceManager クラスの RegisterClasses(string directoryPath) メソッドを呼び出します。引数には dlls サブディレクトリのパスを与えます。
RegisterClasses メソッドは引数のディレクトリから始まるディレクトリ階層を再帰的に巡回して、適切な名前を持つ .dll ファイルを探索します。
.dll ファイルが見つかったら、その中から、IEmbedPrototype 派生クラスを探します。
IEmbedPrototype
IEmbedPrototype クラスは動的なクラス組み込みのためのインターフェースクラスです。
1: | public interface IEmbedPrototype { |
2: | void Embed(string path); |
3: | } |
RegisterClasses() メソッドは IEmbedPrototype 派生クラスを見つけたら、Embed() メソッドを呼び出します。
public void Embed(string path)
上記の手順で .dll ファイル内の Embed() メソッドが呼ばれます。この Embed() メソッドは .dll ファイルのプロジェクトに含まれているのですから、クラス名とデリゲートを知っています。
つまり、AddBuiltIn() メソッドを呼び出してクラスを登録することができます。
Embed(string path) メソッドが呼び出されたとき、.dll ファイルの絶対パスが path 引数として渡されます。
テンプレートの修正
テンプレートを fake クラスのために修正します。
1: | public class RfakeEmbedder : IEmbedPrototype { |
2: | public void Embed(string path) { |
3: | RiceManager.AddBuiltIn(Rfake.TYPENAME, Rfake.InstanceGenerator); |
4: | } |
5: | } |
クラス名を変更して fake クラスの名前とデリゲートで AddBuiltIn() メソッドを呼び出しています。