1

私の同僚が少し前に非常に疑わしいコードを書き、最終的にそれが壊れてしまいました。簡単なサンプルを次に示します。

Assembly assembly = typeof(SmtpClient).Assembly;
Type _mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); //getting a reference to internal class

//create an instance of System.Net.Mail.MailWriter storing it into _mailWriter variable
//It's internal, but for now it still works

MethodInfo _sendMethod = typeof(MailMessage).GetMethod("Send",BindingFlags.Instance | BindingFlags.NonPublic);

//calling non-public method resulting in app crash
_sendMethod.Invoke(
    message,
    BindingFlags.Instance | BindingFlags.NonPublic,
    null,
    new object[] { _mailWriter, true },
    null);

MailMessage.Sendいくつかの調査の後、私の開発マシンには実際にメソッドの2つのパラメーターがあることが判明しました。

System.Net.Mime.BaseWriter writer
Boolean sendEnvelope

ただし、QA エンジニアは最近 VisualStudio 2012 をインストールし、.NET 4.5 をインストールしました。そのため、QA 担当者がアプリケーションを実行しようとすると、System.Reflection.TargetParameterCountException. そして、MailMessage.Send.NET 4.5 で 3 番目のパラメーターを取得したようです。

System.Net.Mime.BaseWriter writer
Boolean sendEnvelope
Boolean allowUnicode

もちろん、このコードを再実装して、非パブリック インターフェイスの使用を停止する必要があります。ただし、プロジェクトのスケジュールがタイトなため、今は余裕がありません。

ここで質問があります。リフレクションを介してアセンブリの古いバージョン (.NET 4.0 など) を参照する方法はありますか?

4

2 に答える 2

3

でアセンブリをロードする代わりに、でtypeof(SmtpClient).AssemblyアセンブリをロードできますAssembly.Load(AssemblyName)

AssemblyNameアセンブリの一意の ID を完全に記述します。例えば:

ExampleAssembly, Version=1.0.0.0, Culture=en, PublicKeyToken=a5d015c7d5a0b012

完全なアセンブリ名でバージョン管理情報を指定できます。

これは、より多くの例を含む MSDN ドキュメントです。

于 2012-09-14T07:46:34.963 に答える
0

具体的にするには、これを行います

var systemNet35 = Assembly.Load(
    @"System.Net, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL");

Type _mailWriterType = systemNet35.GetType("System.Net.Mail.MailWriter");

もちろん、これは .Net 3.5 がインストールされている場合にのみ機能します。

于 2012-09-14T08:04:52.543 に答える