4

私が必要としているのは、.net の人々が「透過的な動的プロキシ」と呼ぶものだと思いますが、これまでに見たすべての実装 (Castle DynamicProxy、Spring.NET AOP など) では、少なくとも次のいずれかを実行する必要があります。

  1. インターセプトされたメソッドを仮想として宣言する
  2. クラスをラップし、ラップされたクラスの代わりにラッパーのインスタンスを作成します
  3. 継承の変更またはインターフェイスの実装

明らかに、呼び出し元と呼び出し先の両方が非仮想であり、サードパーティのクローズド ソース ライブラリからのものである場合、私にできることは何もありません。

C# が Python のような動的言語である場合、次のようにします。

foo = ThirdyPartyLibA.Foo()
def interceptor(self, *args, **kwargs):
    do_something_before(self, *args, **kwargs)
    result = ThirdyPartyLibB.Bar.intercepted(self, *args, **kwargs)
    do_something_after(self, result, *args, **kwargs)
    return result
foo.bar.intercepted = interceptor # bar is an instance of ThirdyPartyLibB.Bar
foo.do_its_job() # Foo.do_its_job calls Bar.intercepted

これは、ThirdyPartyLibB.Bar と対話しているときに ThirdyPartyLibA.Foo の悪い動作を変更するために必要です。この動作の原因と、逆アセンブラーのおかげでこのバグを修正するために Foo または Bar を変更する方法を正確に知っています。

いくつかの (ほとんど機能しない) アイデア:

  • ThirdyPartyLibA を逆アセンブルし、コードに変更を加えて、互換性のあるアセンブリを生成します (厳密な名前のアセンブリであるため、機能しない可能性があります)。
  • バイナリを編集してFooのバグのあるメソッドを仮想化し、有効なアセンブリを維持するために必要なものをすべて変更して、動的プロキシを使用できるようにします(上記のアイデアと同じ理由により、機能する可能性はほとんどありません)
  • 適合する透過的な動的プロキシの実装を見つけます (このフォーラム スレッドに基づくものはないと思います: http://www.pcreview.co.uk/forums/overriding-non-virtual-methods-using-il-and-reflection-エミット-t2605695.html )
  • ライブラリを作成した会社に連絡してください (その会社は製品をサポートしていません)。
  • ライブラリの使用を中止するか、別の方法を使用してください (IDE 独自の言語を使用して書かれた膨大な量のコードがあるため、RAD IDE のランタイムの一部であるため不可能です)。
  • 問題のあるメソッドの呼び出しを制御して、バグを回避します (既にこれを実行しましたが、問題を完全に解決することはできませんでした)。

他に何か考えはありますか?

PS: 下手な英語で申し訳ありません。また、私のPythonで申し訳ありません。このコードは、私が必要とするものを説明するためのものです。恐ろしいので、レシピと見なさないでください。

4

2 に答える 2

3

考えられる解決策 1:

ライブラリをラップし、ReSharper などのツールを使用してライブラリのすべての使用箇所を見つけ、ラッパー クラスに置き換えます。また、その機会を利用して、サード パーティ ライブラリのおそらく粗悪なインターフェイスをクリーンアップすることもできます。

考えられる解決策 2:

TypeMockは通常、テスト ツールとして使用されますが、すべてをモックすることができます。それ自体をコード プロファイラーとして挿入するため、モックできるものには、クラスのプライベート メンバーと静的メンバーが含まれていました。おまけとして、オーバーライドされたメソッドは仮想である必要がないため、その方法で呼び出しをインターセプトできる場合があります。

私のおすすめ

解決策 1 をお勧めします。ラッパーは非常に理解しやすく、コードを実際に改善する良い機会になります。原則として、サードパーティのライブラリをラップすることをお勧めします。

于 2012-08-01T16:17:17.623 に答える
1

Bar が static の場合、 Molesを使用してメソッド呼び出しを迂回できる場合があります。これはバグを修正するための非常に手間のかかるアプローチであり、実際には製品コードにはお勧めできませんが、どうしても必要な場合はオプションです。

于 2012-08-01T16:10:24.930 に答える