2012-12-12 51 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)看起来正是我想要做的事情。 –