DynamicProxy実験3

自作DynamicProxyの続きです。
コンストラクタに続いてメソッドのGenerateにも挑戦、簡易DynamicProxyを作ることが出来ました…一応…。


作成するメソッドについてですが、指定されたinterfaceの全メソッドについて、Intercepterに処理を委譲するILを構築します。
生成するコードについては、C#で書くとこんなカンジになるものを想定します。
methodInfoについては、interfaceとそのMethodInfoを管理するリポジトリから取得する形(OpCodes.CallなILを生成)にしています。

this.__intercepter.Invoke( this.__target, methodInfo, new object[] { ... } );

で、このメソッドのIL生成が結構面倒なものでして(´・ω・`)
例えば戻り値については、void、ValueType、その他等で切り分ける必要がありますし。
OpCodes.Unboxが必要かそうでないかとか。


最初に「一応」と書いたように、とりあえずIntercepter経由の動作までは確認できたんですが、問題点もいくつかみつけました。
例えば、現在の実装では引数パラメータがrefやoutに対応していなかったりします。
他にも、戻り値についての切り分けが現状のものだけで十分なのか不安だったり。


…っというわけで、不完全な実装なのでコードは省略します(´ω`)


ついでにこれ以上調査を進めるのも面倒になったので、自作DynamicProxyについてはストップします('A`)


結論
「.NETでDynamicProxyしたい時は、Castle.DynamicProxyを使いましょう(゚∀゚)」


DynamicProxyの自作を止めたのは、ILGenerator.Emit()によるILの構築が分かりづらいコードになってきたというのも理由にありますが( ´д)


ちなみに、ILの生成に関してCastle.DynamicProxyはどういう風になっているのかというと。
Castle.DynamicProxyでは、Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST名前空間のクラスを使用してILを生成しています。
abstractなStatement、Expression、Reference等のクラスがあり、実装としてReturnStatement、ConvertExpression、LocalReference、FieldReference等のクラスがあります。
StatementやExpressionクラスはEmit()メソッドを持っており、実装クラスでは対応するILを生成するようになっています。
で、これらのクラスでコードイメージを構築してEmit()すると、対応するILが生成されるという作りになっています。


どう考えてもこっちのがスマートです、本当にありがとうございました。