简体   繁体   English

为每个提供商实施电子邮件验证的正确设计模式是什么?

[英]What is the correct design pattern to implement email validation for each provider?

I have to validate email through several validators. 我必须通过几个验证器来验证电子邮件。 I have class( EmailValidator ) that has list of validators( RegexValidator , MXValidator ...) and it validates email through that validators. 我有一个类( EmailValidator ),该类具有验证器列表( RegexValidatorMXValidator ...),它通过该验证器验证电子邮件。 RegexValidator , for example, has its own validators for each provider. 例如, RegexValidator对每个提供程序都有其自己的验证器。 If it recognizes that this is gmail , so it check if it match specific pattern, if it is mygmail , so it checks if it match mygmail's pattern otherwize it return true. 如果它识别出这是gmail ,那么它将检查它是否匹配特定的模式,如果它是mygmail ,那么它将检查它是否匹配mygmail的模式,否则返回true。 MXValidator will validates something else. MXValidator将验证其他内容。

What is the correct design pattern to implement this? 实现此目的的正确设计模式是什么?

public interface IValidator
{
   bool Validate(string email);
}
public class RegexValidator : IValidator
    {
        private const string EMAIL_REGEX = @"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b";
        public bool Validate(string email)
        {
            var regex = new Regex(EMAIL_REGEX);
            var isEmailFormat regex.IsMatch(email);
            if(isEmailFormat)
            {
                 //here it should recognize the provider and check if it match the provider's pattern
            }

            return true;
        }
    }

Chain of Responsibility. 责任链。

As soon as one validator finds invalid pattern, returns false. 一旦一个验证者发现无效模式,就返回false。 You pass an ordered list of validators. 您传递验证程序的有序列表。

bool ValidateEmail(string email, IEnumerable<IValidator> validators, ref errorMessage)
{
    return !validators.Any(v => !v.Validate(email, ref errorMessage);
}

Assuming 假设

interface IValidator
{
    bool Validate(object value, ref errorMessage);
}

UPDATE UPDATE

I see this implemented as another validator: 我将其作为另一个验证器实现:

public class EmailDomainValidator : IValidator
{

   public EmailDomainValidator(string domain)
   {
      _domain = domain;
   }

   ...
}

It's not a direct answer to your problem but I think that you are doing it wrong. 这不是您问题的直接答案,但我认为您做错了。

The real validation of an email is not based on his string representation, but with a simple test. 电子邮件的真实验证不是基于他的字符串表示形式,而是一个简单的测试。 You send a mail, someone answer, the mail is good. 您发送邮件,有人回答,邮件很好。 Otherwise it's bad. 否则不好。

You have an infinity of valid mail address that are not valid in the real world because they are not related to a mailbox. 您有无限个有效邮件地址,这些地址在现实世界中是无效的,因为它们与邮箱无关。

Maybe you are already aware of that and it's your job to do this thing, but if it's not, I suggest you to make a really simple and permissive Regex like: 也许您已经意识到这一点,要做这件事是您的工作,但是如果没有,我建议您制作一个非常简单且允许的正则表达式,例如:

(?<=[\w-\.@]+@)[\w-\.]+

Wich will show you only the part after the @ and will contains a lot of false positive that you can test easily. Wich将仅向您显示@之后的部分,并且包含许多误报,您可以轻松对其进行测试。


About the chaining the validators, I'll make a List<Func<string,bool>> wich contains all the tests and call all them in a foreach loop, throwing and catching an exception in case of false. 关于链接验证器,我将创建一个List<Func<string,bool>>其中包含所有测试,并在foreach循环中调用所有测试,并在错误的情况下引发并捕获异常。

EDIT: in fact, the LINQ method with a lambda is far better. 编辑:实际上,带有lambda的LINQ方法要好得多。 Throwing an exception is expensive. 引发异常的代价很高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM