1

別の質問でこれを見逃した場合は、お詫び申し上げます。独自の質問があると判断する前に、しばらくの間探しました... 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、お守りのように機能します。誰かが私が間違っていることを見ていますか?

ありがとう!

4

1 に答える 1

2

正直、これは仕方のないことだと思います。実装を生成するためにコンテナーが必要な場合はINotifyPropertyChanged、コンテナーによって構築されるモデル オブジェクトをプラグインしている場合がおそらくあります。依存関係などがあるためです。そのような場合CreateClassProxy<T>(interceptors)は問題ありません。他のすべてのケースでは、MVVM ViewModel を使用しており、ユーザー エクスペリエンスに重点を置いて、変更通知を取り巻く正確なロジックがケースバイケースで決定されます。モデルクラスは通常、何らかの方法でフラット化または変換されるため、全体のポイントは議論の余地があります。この質問をしたのは、自分のアプリで MVVM を適切に活用する方法を理解していなかったときであり、より多くの可動部分を担当することになると思っていました。実際には、予想よりもはるかに簡単でした。

于 2012-01-02T19:50:03.253 に答える