現在、オブジェクトの装飾された属性に自動監査を追加する AOP システムを実装しようとしています (の拡張バージョンによって行われますINotifyPropertyChanged
)。自動監査には、古い値と新しい値の propertyName が含まれます。
ツールの使用方法に関する優れたチュートリアル (つまり、これ:: http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx ) があるため、現在、Castle の DynamicProxy2を使用しています。 . 型に合わせて装飾された各プロパティのデリゲートを生成します。式ツリーは次のようなものを生成します:: (コードはタイプ セーフなリフレクション ライブラリと多くの静的変数に依存しているため、式ツリー コードを貼り付けるよりも簡単だと思います)
.Lambda #Lambda1<System.Action`1[Castle.DynamicProxy.IInvocation]>(Castle.DynamicProxy.IInvocation $invocation) {
.Block(
DutchTest.MixinTest $target,
System.Object $argument,
System.DateTime $newValue,
System.DateTime $oldValue) {
$target = (DutchTest.MixinTest).Call $invocation.get_InvocationTarget();
$newValue = .Unbox($argument = .Call $invocation.GetArgumentValue(.Default(System.Int32)));
.If (
.Call (.Call System.Collections.Generic.EqualityComparer`1[System.DateTime].get_Default()).Equals(
$oldValue = .Call $target.get_Created(),
$newValue)
) {
.Default(System.Void)
} .Else {
.Block() {
.Call $invocation.Proceed();
.Call ($target .As Dutch.Auditing.INotifyAuditedChange).OnPropertyChanged(.New Dutch.Auditing.AuditEventArgs(
"Created",
(System.Object)$oldValue,
$argument))
}
}
}
}
次に、(IInterceptor を実装するクラスを選択するカスタム セレクターがありDelegatedInterceptor
、その Intercept メソッドはデリゲートを呼び出すだけです。また、委任する予定のプロパティのみを選択するカスタム フックもあります (したがって、 get メソッドをプロキシします)。
残念ながら、これらすべての予防策を講じても、すべてのプロパティ セットでパフォーマンスに大きな影響が見られます (そのロジックを手動で実行するには約 0.4 ティック、動的プロキシを使用すると約 2.2 ティック、必要な場合は 2.8 ティックが必要です)。のロジックを mixinINotifyAuditedChange
すると、イベントが発生します)。これはそれほど悪くはありませんが、私の要件の一部として、非常に大量のオブジェクトが変更されていることを確認しています。
残念ながら、typebuilder を使用する私の計画は失敗しました (Reflection.Emit でコードを書くのは難しすぎて、明らかに CompileToMethod をインスタンス メソッドに使用することはできません)。DynamicProxy2 のパフォーマンスを改善するために欠けているトリックはありますか?