2012-12-12 50 views
2

我最近開始在Unity應用程序塊使用攔截,並有令人困惑的問題,試圖得到嵌套的屬性,以提醒他們從模型中的視圖模型被改變。例如,我有一個將System.Drawing.Point作爲公共屬性的模式。在視圖模型我有一個返回一個字符串格式呈現的點作爲一個有效的和清晰的價值的公共屬性。不過,我想我已經沒有正確註冊攔截或最終目標是不可能的團結攔截。團結攔截(AOP)嵌套虛擬財產

我已經註冊了我的容器的攔截並設置了一個策略來攔截所有虛擬方法並設置規則以捕獲所有設置的事件 - 對於我來說,儘管我很難理解如何觸發視圖模型檢測/知道模型屬性已更改。我想,「易」的解決辦法是向視圖模型的財產型號特異性結合,然後用自定義格式的用戶界面,以確保值顯示正確,雖然。

如果誰能給有關單位截留一些指針,這將是盛大的。

Container.AddNewExtension<Interception>(); 

PolicyDefinition policyDefinition = 
      Container.Configure<Interception>() 
       .SetInterceptorFor<MyModel>(new VirtualMethodInterceptor()) 
       .SetInterceptorFor<MyViewModel>(new VirtualMethodInterceptor()) 
       .AddPolicy("NotifyPolicy"); 

policyDefinition.AddMatchingRule(new PropertyMatchingRule("*", PropertyMatchingOption.Set)); 


public class MyModel 
{ 
    [NotifyPropertyChanged] 
    public virtual Point APoint { get; set; } 
} 

public class MyViewModel 
{ 
    private MyModel _myModel; 

public MyViewModel() 
{ 
     _myModel = new MyModel { APoint = new Point(3, 2) }; 

    // {12,8} is not reflected in the UI 
    _myModel.APoint = new Point(12, 8); 
    } 

[NotifyPropertyChanged] 
public virtual string ModelLocation 
{ 
     get 
    { 
      return string.Format("'{0}, {1}'", _myModel.APoint.X, _myModel.APoint.Y); 
      } 
    } 
} 

我使用從http://www.codeproject.com/Articles/140042/Aspect-Examples-INotifyPropertyChanged-via-Aspects的NotifyPropertyChangedAttribute和NotifyPropertyChangedHandler作爲一個例子要連接東西;我已經包含了這些方法僅供參考。

[AttributeUsage(AttributeTargets.Property)] 
public class NotifyPropertyChangedAttribute : HandlerAttribute 
{ 
    public override ICallHandler CreateHandler(IUnityContainer container) 
    { 
     return new NotifyPropertyChangedHandler(); 
    } 
} 

internal class NotifyPropertyChangedHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     var result = getNext()(input, getNext); 

     if (input.MethodBase.Name.StartsWith("set_")) 
     { 
      var propertyName = input.MethodBase.Name.Substring(4); 
      var pi = input.Target.GetType().GetProperty(propertyName); 

      if (pi.HasAttribute<NotifyPropertyChangedAttribute>()) 
      { 
       var baseType = input.Target.GetType().BaseType; 
       if (baseType != null) 
       { 
        var info = 
         baseType.GetFields(
          BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) 
          .FirstOrDefault(f => f.FieldType == typeof(PropertyChangedEventHandler)); 

        if (info != null) 
        { 
         var propertyChangedEventHandler = info.GetValue(input.Target) as PropertyChangedEventHandler; 
         if (propertyChangedEventHandler != null) 
          propertyChangedEventHandler.Invoke(
           input.Target.GetType(), new PropertyChangedEventArgs(propertyName)); 
        } 
       } 
      } 
     } 

     return result; 
    } 

    public int Order { get; set; } 
} 

回答

3

當您註冊視圖模型,這是不夠的只是做虛擬方法攔截器,你還需要將其註冊使用PolicyInjectionInterceptor(我認爲)政策注入。

我不過嚴重推薦看着NotifyPropertyWeaver,這將給你INotifyPropertyChanged的在編譯時的功能,而不需要一個統一的政策。

+0

歡呼聲 - NotifyPropertyWeaver [鏈接](http://visualstudiogallery.msdn.microsoft.com/bd351303-db8c-4771-9b22-5e51524fccd3)看起來正是我想要做的事情。 –