public function validate()
    {
        if( ! defined( "structclass-AnnotationRegistry-initilised" )){
            define( "structclass-AnnotationRegistry-initilised", true );
            AnnotationRegistry::registerLoader(function ($class) {return class_exists($class);});
        }
        $validator = Validation::createValidatorBuilder()
            ->enableAnnotationMapping()
            ->getValidator();

        $violations = $validator->validate($this);
        $errs = '';
        if( $violations->count() > 0 ){
            $errs = 'Invalid properties in '.get_called_class()."\n";
            /** @var \Symfony\Component\Validator\ConstraintViolationInterface $issue */
            foreach( $violations as $issue ){
                $errs .=
                    $issue->getPropertyPath()
                    ." : "
                    .$issue->getMessage()
                    . " But got "
                    . var_export( $issue->getInvalidValue(), true );
            }
        }
        // Validate any properties which are StructClasses or are arrays containing StructClasses
        foreach ($this as $property) {
            if ($property instanceof StructClass) {
                try{
                    $property->validate();
                }catch( \Exception $e ){
                    $errs .= $e->getMessage();
                }
            }elseif (is_array( $property )) {
                foreach ($property as $element) {
                    if ($element instanceof StructClass) {
                        try{
                            $element->validate();
                        }catch( \Exception $e ){
                            $errs .= $e->getMessage();
                        }
                    }
                }
            }
        }
        if ($errs != '') {
            throw new \Exception( $errs );
        }
    }