dotnet
dotnet copied to clipboard
Add source generation: "NotifyDataErrorInfoFor"
Overview
We already have the [NotifyDataErrorInfo] attribute, which adds source generation to validate this property.
But since we can use custom validation methods to perform multi-property validation, we should have a way to indicate that Property A influences the validation of Property B.
API breakdown
Add an attribute, NotifyDataErrorInfoForAttribute, which influences the source generator to add validation of other properties.
Right now, the generated setter for a property with [NotifyDataErrorInfo] looks like this:
if (!global::System.Collections.Generic.EqualityComparer<string?>.Default.Equals(path, value))
{
OnPathChanging(value);
OnPathChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Path);
path = value;
ValidateProperty(value, "Path");
OnPathChanged(value);
OnPathChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Path);
}
After the change, it would look like this:
if (!global::System.Collections.Generic.EqualityComparer<string?>.Default.Equals(path, value))
{
OnPathChanging(value);
OnPathChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Path);
path = value;
ValidateProperty(value, "Path");
ValidateProperty(SomeOtherProperty,"SomeOtherProperty"); // <---- THIS LINE IS NEW
OnPathChanged(value);
OnPathChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Path);
}
Usage example
[NotifyDataErrorInfoFor(nameof(Path))] // <--- NEW ATTRIBUTE
private bool isRequired;
[ObservableProperty]
[NotifyDataErrorInfo]
[CustomValidation(typeof(FileSystemLocationViewModel), nameof(ValidatePath))]
private string? path;
public static ValidationResult? ValidatePath(string? path, ValidationContext context)
{
var instance = (FileSystemLocationViewModel)context.ObjectInstance;
if (string.IsNullOrWhiteSpace(path))
{
if (instance.IsRequired)
return new ValidationResult("Path is required");
return ValidationResult.Success;
}
if(IsValidPath(path))
return ValidationResult.Success;
return new ValidationResult("Invalid path provided");
}
Breaking change?
No
Alternatives
Workaround (available now):
Manually implement the property
private bool isRequired;
public bool IsRequired
{
get => this.isRequired;
set
{
if (this.SetProperty(ref this.isRequired, value))
this.ValidateProperty(this.Path, nameof(this.Path));
}
}
Additional context
No response
Help us help you
No, just wanted to propose this