这是如何工作的 - .NET魔法(未记录的功能?)

时间:2013-04-21 20:23:21

标签: .net attributes custom-attributes

找到 this code

这是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中,则验证正常,但ViewModel不会直接实现 IDataErrorInfo ,这是WPF挂钩以使其验证正常工作。然而它可以工作,不知何故它能够从某个地方使用这个ValidationTemplate任意对象。

  4. 更新:因此,在我检查调试器中的PersonViewModel之后,以下产生了有趣的答案:

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

    代码基于Caliburn.Micro,引导程序是vanilla,其中没有任何内容。我手动实例化PersonViewModel以确认它不是调用extender类的WPF特定行为,并且我确实在Target属性触发时得到了setter / getter。

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

2 个答案:

答案 0 :(得分:1)

该项目依赖于Hereder。整天都在寻找我,直到我检查csproj并看到后期构建任务。现在它是有道理的。

答案 1 :(得分:0)

这里没有魔力。属性是.NET中记录良好的特性。属性本质上是一些关于可以添加的类的额外信息,可以通过反射访问。您可以阅读更多相关信息here

编写良好的MVVM代码通常看起来很像“魔术”。实际上,通常有一个编写良好的框架,它使用反射和其他技巧来自动连接它。很可能很多实际工作都是在Caliburn.Micro.dll或FluentValidation.dll中完成的。这样你就可以编写一次bootstrap逻辑,只需在你的所有WPF / Silverlight /等上重复使用它。项目。除非您有这些代码,否则您可以使用像建议here那样的反射器工具来查看它们,或者只是与GitHub仓库的所有者交谈,看看您是否也可以访问这些代码。