別の質問でこれを見逃した場合は、お詫び申し上げます。独自の質問があると判断する前に、しばらくの間探しました... DynamicProxy2を使用して、WPFアプリケーションのモデルクラスのインターセプトを提供したいと思います。これは、INotifyPropertyChangedをどこにでも完全に実装する必要がないようにするためです。たとえば、以下のクラスは、プロキシおよびインターセプトされた後、双方向のデータバインディングに完全に参加する必要があります。
public class ModelExample : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Id{ get; set; }
public string Uri{ get; set; }
public string Name{ get; set; }
}
CreateClassProxyメソッドを呼び出すことで、モデルクラスの新しいインスタンスを作成し、そのインスタンスへの呼び出しをインターセプトできることがわかりました。
new ProxyGenerator().CreateClassProxy<T>(interceptors);
残念ながら、これにより、ProxyGenerator
クラスがモデルインスタンスを作成できるようになり、中間層からそれらを取り戻すことになります。つまり、それらはすでに存在します。既存のオブジェクトをラップする必要があるので、代わりに呼び出す必要があると思います。CreateClassProxyWithTarget
new ProxyGenerator().CreateClassProxyWithTarget(instance, interceptors);
ただし、これを行うと、インターセプターが機能しなくなります。インターセプターのせいではないと確信しています...非常に単純なオブジェクトです。そのインターフェースは次のとおりです。
public interface IFluentInterceptor : IInterceptor
{
IFluentInterceptor Before(Action<IInvocation> before);
IFluentInterceptor After(Action<IInvocation> after);
IFluentInterceptor Finally(Action<IInvocation> @finally);
IFluentInterceptor RunCondition(Func<IInvocation, bool> runCondition);
IFluentInterceptor OnError(Func<IInvocation, Exception, bool> onError);
}
タイプはこれFluentInterceptor
を実装します。、、などのBefore
メソッドAfter
は単純すぎて表示できません。それらはすべて、メソッドの呼び出し中に使用されることを意図したアクションキューに追加され、その後、各メソッドが戻りthis
、メソッドの連鎖が可能になります。
以下のコードは機能しませんが、理由がわかりません。
new ProxyGenerator().CreateClassProxyWithTarget(instance, new FluentInterceptor()
.After(invocation =>
{
if (!invocation.Method.Name.StartsWith("set_")) return;
string propertyName = invocation.Method.Name.Substring(4);
FieldInfo info = invocation.TargetType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(f => f.FieldType.Equals(typeof (PropertyChangedEventHandler)))
.FirstOrDefault();
if (info == null) return;
var handler = info.GetValue(invocation.InvocationTarget) as PropertyChangedEventHandler;
if (handler != null) handler.Invoke(invocation.TargetType, new PropertyChangedEventArgs(propertyName));
}));
で試してみるとCreateClassProxy
、お守りのように機能します。誰かが私が間違っていることを見ていますか?
ありがとう!