質問

ソフトウェアで動的にロード可能なプラグインを作成する何らかの方法を提供したいと考えています。これを行う一般的な方法は、 ロードライブラリ DLL をロードして呼び出すための WinAPI 関数 GetProcAddress その DLL 内の関数へのポインターを取得します。

私の質問は、C#/.Net アプリケーションにプラグインを動的にロードするにはどうすればよいですか?

役に立ちましたか?

解決

次のコード スニペット (C#) は、次のコードから派生した具象クラスのインスタンスを構築します。 Base アプリケーション パスのクラス ライブラリ (*.dll) で見つかり、リストに保存されます。

using System.IO;
using System.Reflection;

List<Base> objects = new List<Base>();
DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);

foreach (FileInfo file in dir.GetFiles("*.dll"))
{
    Assembly assembly = Assembly.LoadFrom(file.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(typeof(Base)) && type.IsAbstract == false)
        {
            Base b = type.InvokeMember(null,
                                       BindingFlags.CreateInstance,
                                       null, null, null) as Base;
            objects.Add(b);
        }
    }
}

編集: によって参照されるクラス マット おそらく .NET 3.5 ではより良いオプションです。

他のヒント

.NET 3.5 では、.NET アプリケーションからプラグインを作成およびロードするための、形式化された組み込みの方法が存在します。それはすべて含まれています システム.アドイン 名前空間。詳細については、MSDN の次の記事をご覧ください。 アドインと拡張性

プラグインの動的ロード

.NET アセンブリを動的にロードする方法については、「」を参照してください。 この質問 (そして 私の答え)。これは、ロードを作成するためのコードです。 AppDomain そしてそこにアセンブリをロードします。

var domain = AppDomain.CreateDomain("NewDomainName");
var pathToDll = @"C:\myDll.dll"; 
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName) 
    as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

プラグインのアンロード

プラグイン フレームワークの一般的な要件は、プラグインをアンロードすることです。動的にロードされたアセンブリをアンロードするには (例:プラグインとアドイン)を含むものをアンロードする必要があります AppDomain. 。詳細については、を参照してください。 AppDomain のアンロードに関する MSDN のこの記事.

WCF の使用

があります スタックオーバーフローに関する質問と回答 Windows Communication Framework (WCF) を使用してプラグイン フレームワークを作成する方法について説明します。

既存のプラグイン フレームワーク

私は 2 つのプラグイン フレームワークを知っています。

について話す人もいます。 マネージド拡張性フレームワーク (MEF) プラグインまたはアドイン フレームワークとしてではありませんが、そうではありません。詳細については、を参照してください。 この StackOverflow.com の質問 そして この StackOverflow.com の質問.

実行中のコードには悪意がある可能性があるため、ヒントの 1 つは、すべてのプラグインなどを独自の AppDomain にロードすることです。独自の AppDomain を使用して、読み込みたくないアセンブリや型を「フィルター」することもできます。

AppDomain domain = AppDomain.CreateDomain("tempDomain");

アセンブリをアプリケーション ドメインにロードするには、次のようにします。

AssemblyName assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
Assembly assembly = domain.Load(assemblyName);

アプリケーション ドメインをアンロードするには、次の手順を実行します。

AppDomain.Unload(domain);

はい、Matt と System.AddIn への ++ (System.AddIn に関する 2 部構成の MSDN マガジン記事が入手可能です) ここ そして ここ)。.NET Framework が将来どのような方向に進むかを知るために検討すべきもう 1 つのテクノロジは、 マネージド拡張性フレームワーク 現在、Codeplex で CTP 形式で入手できます。

基本的には 2 つの方法で実行できます。

1 つ目は、kernel32.dll をインポートし、前に使用したように LoadLibrary と GetProcAddress を使用することです。

[DllImport("kernel32.dll")]

internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]

internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

2 つ目は、.NET の方法で実行することです。反射を利用することで。System.Reflection 名前空間と次のメソッドを確認してください。

まず、パスによってアセンブリを読み込み、次に名前によって型 (クラス) を取得し、次に名前によってクラスのメソッドを再度取得し、最後に関連するパラメーターを使用してメソッドを呼び出します。

この記事は少し古いものですが、アプリケーション内で拡張レイヤーを作成する場合にも適用できます。

ユーザーがマクロとプラグインを使用して .NET アプリケーションに機能を追加できるようにする

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top