2013-04-21 43 views
0

找到this code这是如何工作 - .NET巫术(?无证功能)

这里的gyst:

视图模型:

[ExtendWith(typeof(ValidationTemplate))] 
public class PersonViewModel :INotifyPropertyChanged 
{ 
    public string GivenNames { get; set; } 
    public string FamilyName { get; set; } 

    public string FullName 
    { 
     get 
     { 

      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

ExtendWithAttribute

public class ExtendWithAttribute : Attribute 
{ 
    public ExtendWithAttribute(Type type) 
    { 
    } 
} 

ValidationTemplate

public class ValidationTemplate : IDataErrorInfo 
{ 
    private INotifyPropertyChanged target; 

    public object Target 
    { 
     get 
     { 
      return target; 
     } 
     set 
     { 
      target = (INotifyPropertyChanged)value; 
      validator = ValidationFactory.GetValidator(target.GetType()); 
      validationResult = validator.Validate(Target); 
      target.PropertyChanged += Validate; 
     } 
    } 

    private void Validate(object sender, PropertyChangedEventArgs e) 
    { 
     if (validator != null) 
     { 
      validationResult = validator.Validate(target); 
     } 
    } 

    private IValidator validator; 
    private ValidationResult validationResult; 

    public string Error 
    { 
     get 
     { 
      return string.Join(Environment.NewLine, validationResult.Errors.Select(x => x.ErrorMessage).ToArray()); 
     } 
    } 

    public string this[string propertyName] 
    { 
     get 
     { 
      return string.Join(Environment.NewLine, validationResult.Errors.Where(x => x.PropertyName == propertyName).Select(x => x.ErrorMessage).ToArray()); 
     } 
    } 
} 

如果我们做PersonViewModel的一个实例,我们得到:

  1. ValidationTemplate实例 - 我承担因为我们在类型传递到这个ExtendWith属性.NET自动实例化类型,但我无法找到任何证实此行为的信息

  2. ValidationTemplate Target属性被“神奇地”调用,并且它接收对PersonViewModel的引用。哪些.NET行为片段调用到此?我无法找到任何描述此行为的文档 - 似乎它依赖于命名约定?是否还有其他可以填充的属性?什么巫术是这样:)

  3. 如果该对象在XAML验证只是工作的约束,但视图模型不直接实现IDataErrorInfo的,这是WPF挂钩到得到它的验证工作。但它有效,不知何故,它可以从某处使用此ValidationTemplate任意对象。

更新:所以我检查了PersonViewModel后的调试器下面的产量有趣的答案:

var viewModel = new PersonViewModel(); 
var isDataErrorInfo = viewModel is IDataErrorInfo; // true 
var isDataErrorInfo = viewModel is ValidationTemplate; // false 

的代码是基于Caliburn.Micro,引导程序是香草什么也没有。我手工实例化了PersonViewModel,以确认它不是调用扩展类的WPF特定行为,并且我确实在Target属性触发上获得了setter/getters。

有人可以解释所有这些奇怪的行为。我有一种感觉,这是一些内部/未公开的功能/黑客的.NET框架。

回答

1

该项目依赖于Hereder。我花了整整一天的时间看看,直到我检查csproj并看到了构建任务。现在它是有道理的。

0

这里没有什么魔法可以做。属性在.NET中是一个有据可查的特性。属性本质上是一些关于可以通过反射访问的类添加的额外信息。你可以阅读更多关于它here

写得很好的MVVM代码通常看起来很像“魔术”。实际上,通常有一个写得很好的框架,它使用反射和其他技巧来自动将它们连接起来。很可能很多实际工作都是在Caliburn.Micro.dll或FluentValidation.dll中完成的。这样,您可以一次性编写引导程序逻辑,并将其重用于所有WPF/Silverlight /等。项目。除非你有这些代码,否则你可以使用类似建议here的反射工具来查看它们,或者只是跟GitHub回购站的所有者交谈,看看你是否也可以访问这些代码。

+0

属性的文档是我通过广泛查看并知道这是如何工作的。在这一点上,我确信这是.NET框架的一个内部功能,而不是任何与caliburn/fluent相关的功能,因为我通过将案例简化为新项目来消除这些变量。这是不同的,属性参数中指定的类型的激活由.net框架内部完成,并且它与主类“混合”,也就是说,PersonViewModel正由ValidationTemplate中的代码扩展。我正在寻找记录此行为的材料 – macsux 2013-04-22 00:12:02