2011-12-20 24 views
1

的PropertyChanged我現在有一個setter方法,看起來像這樣:處理PropertyChanging /通過城堡的DynamicProxy

private string _a; 
    public virtual string A 
    { 
     get { return _a; } 
     set 
     { 
      if (_a!= value) 
      { 
       if (this.OnPropertyChanging("A", _a, value)) 
       { 
        var previousValue = _a; 
        _a = value; 
        this.OnPropertyChanged("A", previousValue, value); 
       } 
      } 

     } 
    } 

我有幫助,從威利博士的學徒(http://stackoverflow.com/a/8578507實現了這個/ 981225),具有自定義更改處理程序,可以跟蹤舊的和當前的值,以及將更改事件設置爲「已取消」的功能,使PropertyChange不會發生。

這個效果很好。但是,我們有數百個屬性,這是很多重複的代碼。

我在過去曾使用過Castle的DynamicProxy,以避免必須編寫'OnPropertyChanged(「A」)'。

作爲代理攔截方法的一部分,我如何在此setter中實現邏輯?可能嗎?謝謝。

回答

1

也許我有點晚了,但是我在Linq-To-SharePoint模型中遇到過類似的任務。如果有人仍然在想,我畫了一些代碼。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Castle.DynamicProxy; 
using System.Reflection; 
using System.ComponentModel; 


namespace DemoSpace 
{ 
    public abstract class EntityBase : INotifyPropertyChanged, INotifyPropertyChanging 
    { 
     public virtual void OnPropertyChanging(string propertyName, object value) 
     { 
      if ((null != PropertyChanging)) 
      { 
       PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); 
      } 
     } 

     public virtual void OnPropertyChanged(string propertyName) 
     { 
      if ((null != PropertyChanged)) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public event PropertyChangingEventHandler PropertyChanging; 
    } 

    public class DemoInterceptor<T> : IInterceptor where T : EntityBase 
    { 
     private T _target; 

     public DemoInterceptor(T target) 
     { 
      _target = target; 
     } 

     public void Intercept(IInvocation invocation) 
     { 
      if (invocation.Method.IsPublic && invocation.Method.Name.StartsWith("set_")) 
      { 
       string propertyName = invocation.Method.Name.Substring(4); 
       string privateFieldName = ResolvePropName(propertyName); 


       object original_value = 
        typeof(T).GetField(privateFieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_target); 

       _target.OnPropertyChanging(propertyName, original_value); 
       invocation.Method.Invoke(_target, invocation.Arguments); 
       _target.OnPropertyChanged(propertyName); 

      } 
      else 
      { 
       invocation.ReturnValue = invocation.Method.Invoke(_target, invocation.Arguments); 
      } 

     } 

     public virtual string ResolvePropName(string propertyName) 
     { 
      return "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1); 
     } 

    } 
} 
+0

這是一個好主意,但如果有人決定使用自動屬性而不是帶有後臺屬性的屬性,那麼結果可能非常糟糕。 – 2012-09-14 01:13:08

相關問題