私はSpring.Net1.3.1をMVVMFoundationと一緒に使用して、ビューモデルにクロスカットを適用しています。オブジェクトがクロスカットのためにプロキシに変換される前にプロパティ変更ハンドラーを割り当てると、プロキシエンジンがプロパティ変更ハンドラーをプロキシに適用しないことに気付きました。これが予想される動作であるかどうか、もしそうであれば、回避策があるかどうかを誰かが知っていますか?
私の工場はこんな感じ
public static class AopProxyFactory {
public static object GetProxy(object target) {
var factory = new ProxyFactory(target);
factory.AddAdvisor(new Spring.Aop.Support.DefaultPointcutAdvisor(
new AttributeMatchMethodPointcut(typeof(AttributeStoringMethod)),
new UnitValidationBeforeAdvice())
);
factory.AddAdvice(new NotifyPropertyChangedAdvice());
factory.ProxyTargetType = true;
return factory.GetProxy();
}
}
アドバイスはこんな感じ
public class UnitValidationBeforeAdvice : IMethodBeforeAdvice {
public UnitValidationBeforeAdvice() {
}
public void Before(MethodInfo method, object[] args, object target) {
if (args.Length != 1) {
throw new ArgumentException("The args collection is not valid!");
}
var canConvertTo = true;
if (!canConvertTo) {
throw new ArgumentException("The '{0}' cannot be converted.");
}
}
}
public class NotifyPropertyChangedAdvice : IAfterReturningAdvice, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public void AfterReturning(object ReturnValue, MethodInfo Method, object[] Args, object Target) {
if (Method.Name.StartsWith("set_")) {
RaisePropertyChanged(Target, Method.Name.Substring("set_".Length));
}
}
private void RaisePropertyChanged(Object Target, String PropertyName) {
if (PropertyChanged != null)
PropertyChanged(Target, new PropertyChangedEventArgs(PropertyName));
}
}
プロキシしているオブジェクトは次のようになります
public class ProxyTypeObject : ObservableObject {
private string whoCaresItsBroke;
public string WhoCaresItsBroke {
get { return whoCaresItsBroke; }
set {
whoCaresItsBroke = value;
RaisePropertyChanged("WhoCaresItsBroke");
}
}
}
そして、呼び出しコード
var pto = new ProxyTypeObject();
pto.WhoCaresItsBroke = "BooHoo";
pto.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
return;
};
var proxy = AopProxyFactory.GetProxy(pto);
(proxy as ProxyTypeObject).WhoCaresItsBroke = "BooHoo2";
「WhoCaresItsBroke」プロパティを設定すると、以前に接続したプロパティ変更ハンドラーがヒットしないことに気付くでしょう。(spring.netフォーラムで提供されているNotifyPropertyChangedAdviceを使用してみましたが、機能していないようです。)