2

アプリケーションに単純なプラグインアーキテクチャを実装しています。プラグインの要件は、アプリケーションとプラグインによって参照される* .dllにあるインターフェイス(IPlugin)を使用して定義されます。アプリケーションにはプラグインマネージャー(同じ* .dll内)があり、プラグインフォルダー内のすべての* .dllを検索してプラグインをロードし、プラグインがインターフェイスを実装していることを確認します。私はこれを2つの異なる方法でチェックしました[以前は単純なif(プラグインはIPlugin)でした]が、プラグインがインターフェースを実装するタイミングをどちらも認識しません。コードは次のとおりです。

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (currType.GetInterfaces().Contains(typeof(IPlugin)))
        {
            // Code here is never executing
            // even when the currType derives from IPlugin
        }
    }                    
}

以前は特定のクラス名(「プラグイン」)をテストしていましたが、アセンブリ内のすべてのクラスを循環させても無駄になりました。(これは、他の場所で見つけた例に従います。)これをもう少し複雑にするために、それぞれが元のインターフェイス(IPluginA、IPluginB)を実装する2つのインターフェイスがあります。プラグインは実際には、より具体的なインターフェースの1つ(IPluginB)を実装します。ただし、より一般的なインターフェイス(IPlugin)を実装するだけのプラグインで試してみましたが、それでも機能しません。

[編集:最初に受け取った2つの応答への応答]はい、IsAssignableFromを使用してみました。以下を参照してください。

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (typeof(IPlugin).IsAssignableFrom(currType))
        {
            string test = "test";
        }
    }
}
4

2 に答える 2

5

やってみました:

typeof(IPlugin).IsAssignableFrom(currType)

また、型はインターフェイスを実装しますが、それらから派生しません。BaseTypeプロパティとIsSubclassOfメソッドは派生を示し、IsAssignableFromは派生または実装を示します。

編集:アセンブリは署名されていますか? それらは、アセンブリのサイド バイ サイド バージョンをロードしている可能性があります。Typeオブジェクトは と比較されるためReferenceEquals、2 つのサイド バイ サイド アセンブリの同じタイプは完全に独立しています。

編集2:これを試してください:

public Type[] LoadPluginsInAssembly(Assembly otherAssembly)
{
    List<Type> pluginTypes = new List<Type>();
    foreach (Type type in otherAssembly.GetTypes())
    {
        // This is just a diagnostic. IsAssignableFrom is what you'll use once
        // you find the problem.
        Type otherInterfaceType =
            type.GetInterfaces()
            .Where(interfaceType => interfaceType.Name.Equals(typeof(IPlugin).Name, StringComparison.Ordinal)).FirstOrDefault();

        if (otherInterfaceType != null)
        {
            if (otherInterfaceType == typeof(IPlugin))
            {
                pluginTypes.Add(type);
            }
            else
            {
                Console.WriteLine("Duplicate IPlugin types found:");
                Console.WriteLine("  " + typeof(IPlugin).AssemblyQualifiedName);
                Console.WriteLine("  " + otherInterfaceType.AssemblyQualifiedName);
            }
        }
    }

    if (pluginTypes.Count == 0)
        return Type.EmptyTypes;

    return pluginTypes.ToArray();
}
于 2009-08-13T01:44:34.863 に答える
2

メソッド IsAssignableFrom は、あなたが探しているものです:

Type intType = typeof(IInterface);
foreach (Type t in pluginAssembly.GetTypes())
{
    if (intType.IsAssignableFrom(t))
    {
    }
}
于 2009-08-13T01:46:45.983 に答える