private void ParseLocation(string location)
        {
            var type       = GetType();
            var properties = PropertiesCache.GetFromCacheOrFetch(type, () => type.GetPropertiesEx());
            var dictionary = KeyValueStringParser.Parse(location);

            using (SuspendChangeNotifications(false))
            {
                ValidationContext = new ValidationContext();

                foreach (var property in properties)
                {
                    var propertyName = property.Name;

                    if (dictionary.TryGetValue(propertyName, out var propertyValueStr))
                    {
                        dictionary.Remove(propertyName);

                        SetPropertyValue(property, propertyValueStr);
                    }
                    else
                    {
                        if (property.IsDecoratedWithAttribute(typeof(RequiredAttribute)))
                        {
                            ValidationContext.AddValidationError($"Required field '{propertyName}' is empty");
                        }
                    }
                }
            }
        }
        public virtual bool Validate(IValidationContext validationContext)
        {
            var selfValidationResult = SelfValidate();

            if (!selfValidationResult)
            {
                validationContext.AddValidationError(ErrorMessage());
            }

            ConcurrentBag <bool> bag = new ConcurrentBag <bool>();

            if (_roots != null)
            {
                Parallel.ForEach(_roots, (item) =>
                {
                    bag.Add(item.Validate(validationContext));
                });
            }


            return((_roots == null || bag.All(i => i)) && selfValidationResult);
        }
        public virtual void Validate()
        {
            using (SuspendChangeNotifications(false))
            {
                ValidationContext = new ValidationContext();

                var type       = GetType();
                var properties = PropertiesCache.GetFromCacheOrFetch(type, () => type.GetPropertiesEx());
                foreach (var property in properties)
                {
                    if (!property.IsDecoratedWithAttribute(typeof(RequiredAttribute)))
                    {
                        continue;
                    }

                    var propertyValue = property.GetValue(this);
                    if (propertyValue is null)
                    {
                        ValidationContext.AddValidationError($"Required field '{property.Name}' is empty");
                    }
                }
            }
        }