2

私の問題は、変更がほとんどなく、変更が表示されたエラーにどのように関連しているかを理解していないときに、履歴から古い DLL とは異なる結果が得られることです。

これは、SecurityPluginServices.dll モジュールのメソッドの一部であり、基本的にリストにプラグインを追加して、メイン プログラムで利用できるようにします。

設定されたフォルダー内のすべての DLL を取得し、それぞれについて以下のコードを実行します。

private void AddPlugin(string FileName, LoggingUtilities.Source source)
{
    //Create a new assembly from the plugin file we're adding..
    Assembly pluginAssembly = Assembly.LoadFrom(FileName);

    try
    {
        //Next we'll loop through all the Types found in the assembly
        foreach (Type pluginType in pluginAssembly.GetTypes())
        {
            if (pluginType.IsPublic) //Only look at public types
            {
                if (!pluginType.IsAbstract)  //Only look at non-abstract types
                {
                    //Gets a type object of the interface we need the plugins to match
                    Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);

                    //Make sure the interface we want to use actually exists
                    if (typeInterface != null)
                    {
                     // Do work here
                    }

                    typeInterface = null; //Mr. Clean           
                }
            }
        }

        pluginAssembly = null; //more cleanup
    }
    catch (ReflectionTypeLoadException ex1)
    {
        Console.WriteLine(ex1.Message);
    }
    catch (Exception ex2)
    {
        Console.WriteLine(ex2.Message);
    }
}

私が抱えている問題は、それに到達するたびにType typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);常に null を返すことです。ロードする必要があるプラグインは NTLM と LDAP 用であり、多くのバージョンでほとんど変更されておらず、追加のプロパティとメソッドがいくつか追加されただけで、実装するインターフェイスとは関係ありません。新しいプラグイン DLL のコピーと ILDASM の古いプラグインの 1 つを開いてみましたが、どちらもメソッドが求めてSecurityInterface.ISecurityPluginいるものに関する同じ情報を含んでいるようです。.GetInterface

新しい LdapSecurity

古い LDAP セキュリティ

4

2 に答える 2

2

提案:

Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);
                                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

これを完全修飾タイプ名に変更します。つまり、インターフェイスタイプを含むアセンブリを含む名前に変更します。

(2つの異なるアセンブリに同じ名前の2つの異なるタイプがあり、したがって1つの明確なアセンブリ名を含めることができないと言っている場合、これが問題の原因である可能性があります。)

説明:

私の他の答えは、あなたの問題を引き起こす可能性のあるものの疑いに私を導きました。一般的に、typeof(T)を含むアセンブリのプロジェクトへのアセンブリ参照を追加する必要がありますT。そうしないと、コンパイルが失敗します。一方、などの型名のテキストによる言及はType.GetType("T")、コンパイル時のアセンブリ参照を強制しません...ただし、実行時に型インスタンスに解決する必要があります。Tしたがって、アセンブリ名を省略する場合は、.NETが特定のアセンブリにどのようにマップされるかを覚えておく必要があります。

問題に戻ります。まず、完全修飾型名を使用していないことに注意してください。

Type typeInterface = pluginType.GetInterface("SecurityInterface.ISecurityPlugin", true);
                                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

名前空間とタイプ名のみを指定し、インターフェイスタイプを含むアセンブリは指定しません。インターフェイスタイプが複数回、つまり異なるアセンブリで定義されていて、そのタイプ名についての言及が間違ったアセンブリを入力するように解決された可能性がありますか?

文字列パラメータを次のように説明しているメソッドのMSDNドキュメントをType.GetType(string)簡単に見てみましょう。

「取得する型のアセンブリ修飾名。[…]型が現在実行中のアセンブリまたはにMscorlib.dllある場合は、名前空間で修飾された型名を指定するだけで十分です。」

Type.GetInterface(string, bool)同じことがあなたが使用している方法に当てはまる場合はどうなりますか?また、現在実行中のアセンブリにその名前のタイプが含まれている場合はどうなりますか?次に、それpluginTypeがチェックされるタイプです...ただしISecurityPlugin、プラグインクラスが実際に実装しているものとは異なるインターフェイスタイプ(名前は同じですが)である可能性があります。

于 2013-02-08T10:15:32.080 に答える
1

更新:最初に他の回答を参照してください。これはより関連性が高いと思われます。

pluginTypeがインターフェイスを実装しているかどうかを確認したい場合ISecurityPluginは、代わりに次の確認を実行できます。

typeof(SecurityInterface.ISecurityPlugin).IsAssignableFrom(pluginType)

を含むアセンブリを参照しない場合はISecurityPlugin、最初のパーツを で置き換えることができますType.GetType("SecurityInterface.ISecurityPlugin")

于 2013-02-08T09:29:34.000 に答える