CommunityToolkit / CommunityToolkit/dotnet
Add source generation: "NotifyDataErrorInfoFor"
- Dominant language
- C#
- Stars
- 3.8k
- Forks
- 400
- PR merge metrics
- No merged PRs in 30d
Description
### 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:
```csharp
if (!global::System.Collections.Generic.EqualityComparer.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:
```csharp
if (!global::System.Collections.Generic.EqualityComparer.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
```csharp
[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
```csharp
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
Contributor guide
Assessment
This issue has not been assessed yet.