現在取り組んでいるアプリケーションの将来のプラグイン作成のための適切な契約を設計することを考えていました。基本的にはインターフェースを定義するという考えですが、現在システムに提示されているプラグインをアプリケーションに認識させ、プラグインの開発者がもちろんプラグインの開発者がすべき名前と簡単な説明を含むプラグインの素敵なリストをユーザーに表示する必要がありますアプリケーションのユーザーはこれを簡単に変更できないため、追加の構成ファイルはオプションではありません。これには、アセンブリのファイル名のクラス名を使用したくありません。また、プラグインをインスタンス化せずにアクセスできるはずだと思いますが、おそらくリフレクションを通じて、次のようになりますassembly.GetType(type).GetProperty("Name").GetValue(null, null).ToString();
。もちろん、次のような存在をチェックするロジックを提供できますif(assembly.GetType(type).GetProperty("Name") != null)
、しかし、これも良い考えではありません.プロパティが存在しない場合、エンドユーザーはそのプラグインが何をするのか、その名前が何であるかさえわからないからです。現在、静的プロパティのように動作する必要がありますが、静的はオーバーライドできないため、インターフェイスの一部としても抽象クラスでも宣言できないようです。たぶん私は間違った方向に進んでおり、静的プロパティのようにしか見えず、別のアプローチでこの機能を実現できます。したがって、簡単な質問は、「サードパーティの開発者にプラグインに関するメタ情報を提供するよう強制する方法」です。お知らせ下さい。
3 に答える
次の 2 つのインターフェイスで試すことができます。
IAddIn
すべてのアドインが実装するメイン インターフェイスです。
IAddInInfo
アドインのメタデータ (名前、発行元、説明のバージョンなど) を提供するインターフェイスです。
各アドインは、これらの両方を実装する必要があります。実装は次のIAddInInfo
ようになります。
public class ScannerAddInInfo : IAddInInfo
{
public string Name { get { return "Scanner"; } }
public string Description { get { return "Add-in for acquiring images from a scanner device"; } }
}
アドインのすべての実装にメタデータが付属していることを確認するには、次IAddIn
のような汎用インターフェイスを作成できます。
public interface IAddIn<T> where T : IAddInInfo
{
T Info { get; }
//Continue with the rest of the members you would want every add-in to have.
}
その場合、スキャナー アドインの実装は次のようになります。
public class ScannAddIn : IAddIn<ScannerAddInInfo>
{
private ScannerAddInInfo _info = new ScannerAddInInfo();
public ScannerAddInInfo Info { get { return _info; } }
//Continue with the rest of the IAddIn implementation.
}
次に、特別なアドイン フォルダーからアドイン アセンブリを読み込み、実装する型のインスタンスを作成IAddInInfo
し、アプリケーションで検出されたアドインからの情報を表示できます。アドインはまだ作成されていないことに注意してください。そのためには、リフレクションを追加して、実装している型を見つける必要がありますIAddIn<ScannerAddInInfo>
。
これを簡単にするために、アドイン タイプ名をIAddInInfo
インターフェイスなどに追加できます。
このアプローチの唯一の欠点は、アドインが含まれていない場合でも、特別なアドイン フォルダーにあるすべてのアセンブリを読み込む必要があることです。
これを回避するには、Mono.Cecilを試すことができます。次に、次のようなことを行う必要があります。
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assemblyPath);
foreach (TypeDefinition td in ad.MainModule.GetTypes())
{
if (td.BaseType != null && td.BaseType.FullName == "MyNamespace.MyAddInBase")
{
return true;
}
}
アセンブリを読み込むには、Assembly.LoadFormを使用し、 Activator.CreateInstanceオーバーロードの 1 つであるアドインとアドイン情報のインスタンスを作成します。
幸運を。
あなたがすべきことは、基本的にあなたのインターフェースを定義し、他の人が具体的なクラスを実装し、そのランタイムオブジェクトを何らかの形であなたに与えることを期待することです(あなたの定義済みメソッド、設定など).
しかし、依存性注入と呼ばれるメカニズムがあります。これにより、「システム」がエントリーポイントと実装者の具象のマッチメイキングを処理しながら、インターフェースとエントリーポイントを定義できます。この目的のために「System.ComponentModel.Composition」名前空間があります。
そのような仕事をする「Unity」というフレームワークがあることを知りました。コンポジション名前空間は、ユニティの簡略化されたバージョンであると思います。ヒントについては、「ImportAttribute」および「ExportAttribute」クラスのヘルプを確認できます。
プラグインに「メタデータ」を追加するには、属性を使用できます。プラグインのカスタム属性を作成し、リフレクションで情報を読み取り、アプリケーションに表示します。
属性に関する詳細情報: