Cache validation method information.
MODIFY
WalletWasabi.Gui/ViewModels/Validation/ReflectionHelper.cs
WalletWasabi.Gui/ViewModels/Validation/ReflectionHelper.cs
@@ -50,6 +50,22 @@ namespace WalletWasabi.Gui.ViewModels.Validation
}
}
+ public static MethodInfo GetMethodInfo<T>(object instance, string methodName)
+ {
+ MethodInfo info = instance.GetType().GetRuntimeMethod(methodName, new Type[0]);
+
+ if (info != null &&
+ info.ReturnType == typeof(T) &&
+ info.GetParameters().Length == 0)
+ {
+ return info;
+ }
+ else
+ {
+ throw new ArgumentException("Method was not found on class");
+ }
+ }
+
public static IEnumerable<PropertyInfo> GetPropertyInfos(object instance)
{
return instance.GetType().GetRuntimeProperties();

MODIFY
WalletWasabi.Gui/ViewModels/Validation/Validator.cs
WalletWasabi.Gui/ViewModels/Validation/Validator.cs
+using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
@@ -7,47 +8,54 @@ namespace WalletWasabi.Gui.ViewModels.Validation
{
public static class Validator
{
- public static ErrorDescriptors ValidateAllProperties(object instance)
+ public static IEnumerable<(string, MethodInfo)> PropertiesWithValidation(object instance)
{
- var result = new ErrorDescriptors();
-
- foreach (PropertyInfo property in ReflectionHelper.GetPropertyInfos(instance))
+ foreach (PropertyInfo pInfo in ReflectionHelper.GetPropertyInfos(instance))
{
- var error = ValidateMethod(instance, property);
+ var vma = ReflectionHelper.GetAttribute<ValidateMethodAttribute>(pInfo);
- if (error.Equals(ErrorDescriptor.Default))
- {
- result.AddRange(error);
- }
- }
+ if (vma is null) continue;
- return result;
+ var mInfo = ReflectionHelper.GetMethodInfo<ErrorDescriptors>(instance, vma.MethodName);
+ yield return (pInfo.Name, mInfo);
+ }
}
- public static ErrorDescriptors ValidateProperty(object instance, string propertyName)
+ public static ErrorDescriptors ValidateAllProperties(ViewModelBase viewModelBase,
+ List<(string propertyName, MethodInfo mInfo)> validationMethodCache)
{
- var property = ReflectionHelper.GetPropertyInfo(instance, propertyName);
+ ErrorDescriptors result = null;
- if (property != null)
+ foreach (var validationCache in validationMethodCache)
{
- return ValidateMethod(instance, property);
+ var invokeRes = (ErrorDescriptors)validationCache.mInfo.Invoke(viewModelBase, null);
+
+ if (result is null) result = new ErrorDescriptors();
+
+ result.AddRange(invokeRes);
}
- return ErrorDescriptors.Empty;
+ return result ?? ErrorDescriptors.Empty;
}
- private static ErrorDescriptors ValidateMethod(object instance, PropertyInfo property)
+ public static ErrorDescriptors ValidateProperty(ViewModelBase viewModelBase,
+ string propertyName,
+ List<(string propertyName, MethodInfo mInfo)> validationMethodCache)
{
- var vma = ReflectionHelper.GetAttribute<ValidateMethodAttribute>(property);
+ ErrorDescriptors result = null;
- if (vma != null)
+ foreach (var validationCache in validationMethodCache)
{
- return ReflectionHelper.InvokeMethod<ErrorDescriptors>(instance, vma.MethodName);
- }
- else
- {
- return ErrorDescriptors.Empty;
+ if (validationCache.propertyName != propertyName) continue;
+
+ var invokeRes = (ErrorDescriptors)validationCache.mInfo.Invoke(viewModelBase, null);
+
+ if (result is null) result = new ErrorDescriptors();
+
+ result.AddRange(invokeRes);
}
+
+ return result ?? ErrorDescriptors.Empty;
}
}
}
\ No newline at end of file

MODIFY
WalletWasabi.Gui/ViewModels/ViewModelBase.cs
WalletWasabi.Gui/ViewModels/ViewModelBase.cs
@@ -4,6 +4,7 @@ using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
+using System.Reflection;
using WalletWasabi.Gui.ViewModels.Validation;
using WalletWasabi.Helpers;
@@ -11,13 +12,23 @@ namespace WalletWasabi.Gui.ViewModels
{
public class ViewModelBase : ReactiveObject, INotifyDataErrorInfo
{
+ private List<(string, MethodInfo)> ValidationMethodCache;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
- public bool HasErrors => Validator.ValidateAllProperties(this).HasErrors;
+ public ViewModelBase()
+ {
+ var vmc = Validator.PropertiesWithValidation(this).ToList();
+
+ if (vmc.Count == 0) return;
+
+ ValidationMethodCache = vmc;
+ }
+
+ public bool HasErrors => Validator.ValidateAllProperties(this, ValidationMethodCache).HasErrors;
public IEnumerable GetErrors(string propertyName)
{
- var error = Validator.ValidateProperty(this, propertyName);
+ var error = Validator.ValidateProperty(this, propertyName, ValidationMethodCache);
if (error.HasErrors)
{

Cache validation method information.