private IMethodReturn InterceptPropertySet(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { IMethodReturn result; var propertyName = input.MethodBase.Name.Substring(4); var objectType = input.MethodBase.DeclaringType; var getMethod = objectType.GetMethod(input.MethodBase.Name.Replace("set_", "get_")); var oldValue = getMethod.Invoke(input.Target, null); var newVlaue = input.Arguments[0]; if (!Equals(oldValue, newVlaue)) { var changingHandler = PropertyChanging; if (changingHandler != null) { var changingArgs = GetChangingArgs(input, propertyName); changingHandler(input.Target, changingArgs); } var extChangeNotify = input.Target as IExternalPropertyChangeNotify; if (extChangeNotify != null) { extChangeNotify.OnPropertyChanging(propertyName); } result = getNext()(input, getNext); if (extChangeNotify != null) { extChangeNotify.OnPropertyChanged(propertyName); } var changedHandler = PropertyChanged; if (changedHandler != null) { var changedArgs = GetChangedArgs(input, propertyName); changedHandler(input.Target, changedArgs); List <string> propertyChain; if (_changeWithMap.TryGetValue(propertyName, out propertyChain)) { foreach (var p in propertyChain) { var args = GetChangedArgs(input, p); changedHandler(input.Target, args); } } List <MethodInfo> methodChain; if (_invokeWithMap.TryGetValue(propertyName, out methodChain)) { var methodInvoked = input.Target as IMethodAutoInvoked; foreach (var method in methodChain) { var parameters = method.GetParameters(); if (parameters.Length == 0) { method.Invoke(input.Target, new object[0]); if (methodInvoked != null) { methodInvoked.OnMethodInvoked(method.Name, null); } } else if (parameters[0].ParameterType.IsCompatiableWith <InvokeContext>()) { var invokeContext = InvokeContext.Create(propertyName, oldValue, newVlaue); method.Invoke(input.Target, new object[] { invokeContext }); if (methodInvoked != null) { methodInvoked.OnMethodInvoked(method.Name, invokeContext); } } } } List <IInvalidatableCommand> commandChain; if (_invalidateWithMap.TryGetValue(propertyName, out commandChain)) { foreach (var method in commandChain) { method.Invalidate(); } } } } else { result = getNext()(input, getNext); } return(result); }