2013-04-21 40 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