私が必要としているのは、.net の人々が「透過的な動的プロキシ」と呼ぶものだと思いますが、これまでに見たすべての実装 (Castle DynamicProxy、Spring.NET AOP など) では、少なくとも次のいずれかを実行する必要があります。
- インターセプトされたメソッドを仮想として宣言する
- クラスをラップし、ラップされたクラスの代わりにラッパーのインスタンスを作成します
- 継承の変更またはインターフェイスの実装
明らかに、呼び出し元と呼び出し先の両方が非仮想であり、サードパーティのクローズド ソース ライブラリからのものである場合、私にできることは何もありません。
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で申し訳ありません。このコードは、私が必要とするものを説明するためのものです。恐ろしいので、レシピと見なさないでください。