Custom validators

The ErrorMessage in the example is just up to you. Yes, you should replace it with a hard-coded message, or, if you want it to be customizable from the attribute, you can simply set it when creating the validator.

For instance, consider the Required attribute. This is how it's implemented:

constructor RequiredAttribute.Create(const ErrorMessage: string = ''; const ErrorCode: string = '');
begin
  inherited Create;
  FValidator := TRequiredValidator.Create(ErrorMessage, ErrorCode);
end;

function RequiredAttribute.GetValidator: IValidator;
begin
  Result := FValidator;
end;

You see that ErrorMessage is one of the attribute parameters. It's passed to the TRequiredValidator class. You can do the same with your TMyDataValidator, and use it for your error message.