1

定義済みの物理ファイル パスから DLL を動的にロードするプラグイン アーキテクチャを C#.NET で構築しました。アセンブリが 2 つの場所のメモリ ロケーションに存在する可能性があることを認識しているため、次のようなものを使用してアセンブリ内のメンバー (インターフェイス) を検証することは信頼できません...

if(plugin is T)
    // cache the assembly

...現在、インターフェイス名を使用して比較し、そこからインスタンスをアクティブ化しています。ただし、これにも制限があります。インターフェイス「IPlugin」は、多くのサード パーティ アセンブリ (つまり、log4net など) が使用する非常に一般的なインターフェイス名であるためです。

次のコードを使用します (これは機能しません)。

foreach (Type t in assembly.GetTypes())
{
    type = t;

    if (!type.IsInterface)
    {
        var plugin = type.GetInterface(typeof(T).Name);

        if (plugin != null)
            if (plugin is T)
            {
                T p = (T)Activator.CreateInstance(type);

                if (!this.Plugins.Select(sp => sp.Name).Contains(p.Name))
                    this.Plugins.Add(p);
            }
    }
}

私の質問: 動的にロードされた DLL が IPlugin インターフェイスと一致することを確認するための最良の (信頼できる) 方法は何ですか?

IPlugin の公開キー トークンをハード コードして検証することも考えられますが、もっと正式な方法はないかと考えています。例として、IPlugin 名または公開鍵トークンを偽装するアセンブリによる潜在的なセキュリティ ホールを想像できます。したがって、ロードされた DLL がそれをロードするアセンブリの署名と一致することをテストする良い方法があるかもしれません。

さらに明確にする必要がある場合はお知らせください。

とてもありがたい!

4

4 に答える 4

2

アセンブリですべての型を列挙する代わりに、ファクトリ クラスを定義してみませんか?

ファクトリ クラスには、"YourFramework.PluginTypeFactory" などのより適切な名前が付けられ、名前の競合の可能性が実際に排除されます。

さらに、特定のアセンブリでひどく失敗するAssembly.GetTypes可能性があり、バグ アセンブリに多くの時間がかかります。

于 2012-05-07T15:33:38.953 に答える
1

使用IsAssignableFrom:

var yourIPlugin = typeof(IPlugin);
foreach (Type t in assembly.GetTypes())
{
    if (yourIPlugin.IsAssignableFrom(t))
    {
            T p = (T)Activator.CreateInstance(t);
            if (!this.Plugins.Select(sp => sp.Name).Contains(p.Name))
                this.Plugins.Add(p);
    }
}

IsAssignableFromタイプを使用して、そこから別のタイプを割り当てることができるかどうかを確認します。型の名前だけでなく、実際の型を完全に考慮します。したがって、アセンブリまたは他のアセンブリに という名前IPluginの型が含まれている場合でも、からの 1 つだけyourIPluginが見つかります。

于 2012-05-07T14:01:27.327 に答える
1

私はたまたまあなたと同じ問題を抱えていました.いくつかの「プラグイン」が2回ロードされ、使用時に.NET Frameworkが型を解決できませんでした.

IsAssignableFrom

AppDomain の AssemblyResolve イベントにハンドラーを追加し、現在の AppDomain の Assemblies コレクションに既に読み込まれている場合は「プラグイン」を再度読み込まないことで解決しました。

ほとんどの場合、いくつかのプラグインが相互に依存し始め、アセンブリ ローダーが既に読み込まれている同じアセンブリを何度も何度も読み込んでいました。

それがあなたの問題を解決するのに役立つことを願っています、それは確かに私を夢中にさせました!

于 2012-05-07T15:37:46.673 に答える