Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

As a dev validating a recursive object graph, I would like the validator to support recursion #52

Closed
craigfowler opened this issue Apr 21, 2022 · 2 comments
Assignees
Labels
enhancement A new feature or capability

Comments

@craigfowler
Copy link
Member

craigfowler commented Apr 21, 2022

As a developer writing validation, I would like to be able to recursively apply validation logic to my object model, when a validated value is of a type for which I have already configured sufficient validation.

An example of this kind of validation would be for validating something like a DOM or document format constructed from nodes. In (for example) an HTML DOM, an "Element" node may have child nodes which are themselves "Element" nodes. This may continue to an almost-unlimited degree.

The meaning of recursive validation

The work performed in this ticket needs to deal with both of the scenarios described below.

Primary meaning of recursive validation: "I already know how to validate this type"

At present, the validation framework has no way to express "Validate this value in the same way as a value for which validation was already configured". So, I would need to write new ManifestValue instances for each level of recursion, ad infinitum. This ticket is about supporting that form of recursion, where I say "Validate object of type X in this manner, and if that X contains an object of type Y, which may contain further (different) instances of X, then validate those in the same way as I would have validated the original X".

Another meaning of recursive validation: Circular references

Recursion can have another meaning though, and that is dealing with actual circular references in the validated object model. This is different from the above in that we are dealing with "This object of type X contains an object of type Y, which contains the exact same instance of type X as we already validated". In that scenario we must break the loop of recursion, because otherwise we would create an endless validation loop.

@craigfowler craigfowler changed the title Add support for recursive validation As a dev validating a recursive object graph, I would like the validator to support recursion Apr 22, 2022
@craigfowler craigfowler added the enhancement A new feature or capability label Apr 22, 2022
@craigfowler
Copy link
Member Author

craigfowler commented Jun 22, 2022

Dev approach idea

Validating descendants of the same type

Dealing with the first recursive validation scenario is quite easy. Simply use a circular reference to a previously-used ManifestValue. So one of the ManifestValueBase.Children would be an instance of ManifestValue which has already been configured as part of the overall manifest.

Validating circular references

To validate actual circular references, I think I will need to implement by skipping the validation of any validated values within the validation hierarchy when any of their parent values is a reference to the same object instance. So, when adding any new validated value, if the value is a reference type then move through each of that value's parent validated values. If any of them is a reference to the same object instance with the same validation manifest then skip the current validated value and do not validate it. If the validated value is the same but has a different manifest then it is OK to validate it. Of course, if it is seen again then do not validate it if it is associated with either manifests which were seen already.

Effectively the parent validated values (and the associated manifests) become a form of closed list for the creation of validated values. If a combination of reference & manifest has been seen before then we don't validate it again.

@craigfowler
Copy link
Member Author

There's a problem with the dev approach above. There are a few members of a ManifestValue which should not be taken from the recursive value. These indicate:

  • The member name
  • The accessor function
  • The parent value

Because these need to be distinct for a recursive value, we cannot just reference the original value.

@craigfowler craigfowler self-assigned this Jun 30, 2022
craigfowler added a commit that referenced this issue Jun 30, 2022
This includes a small fix in ValidatedValueFromBasisFactory
related to how an identity is retrieved from a possibly-null
value.  That's not directly related to recursive validation.
craigfowler added a commit that referenced this issue Jun 30, 2022
This allows a manifest model value to be converted to
a recursive manifest value by virtue of a new property.
craigfowler added a commit that referenced this issue Jun 30, 2022
craigfowler added a commit that referenced this issue Jul 1, 2022
This improves the test coverage and refactors
a large service into many independent types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A new feature or capability
Projects
None yet
Development

No branches or pull requests

1 participant