I would recommend you create an IValidator interface then create multiple different validators that handle different scenarios. Here's one example:
public interface IValidator {
bool CanValidateType(string type);
bool Validate(string input);
}
The CanValidateType() method could be a bit more complex, but I hope you get the idea. It basically identifies whether the validator can handle the input supplied. Here are a couple implementations:
public class UrlValidator : IValidator {
bool CanValidateType(string type) {
return type.ToLower() == "url";
}
bool Validate(string input) {
/* Validate Url */
}
}
public class EmailValidator : IValidator {
bool CanValidateType(string type) {
return type.ToLower() == "email";
}
bool Validate(string input) {
/* Validate Email */
}
}
Now you will use constructor injection to inject the dependency into your class:
public class SomeSimpleClass {
private IValidator validator;
public SomeComplexClass(IValidator validator) {
this.validator = validator;
}
public void DoSomething(string url) {
if (validator.CanValidateType("url") &&
validator.Validate(url))
/* Do something */
}
}
The CanValidateType comes in handy when you have a class that can use multiple validators. In this scenario you pass in a list or an array of validators to the constructor.
public class SomeComplexClass {
private List<IValidator> validators;
public SomeComplexClass (List<IValidator> validators) {
this.validators = validators;
}
public bool ValidateUrl(string url) {
foreach (IValidator validator in this.validators)
if (validator.CanValidateType("url"))
return validator.Validate(url);
return false;
}
public bool ValidateEmail(string email) {
foreach (IValidator validator in this.validators)
if (validator.CanValidateType("email"))
return validator.Validate(email);
return false;
}
}
You would then have to pass in the required instance of the validator(s) to your classes somehow. This is often done with an IoC container (like Castle Windsor) or do it yourself.
IValidator emailValidator = new EmailValidator();
IValidator urlValidator = new UrlValidator();
SomeSimpleClass simple = new SomeSimpleClass(urlValidator);
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator });
The above code gets tedious to do on your own, this is why IoC containers are so handy. With an IoC container you can do something like the following:
SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();
All the mapping of interfaces is done in your app.config or web.config.
Here's an awesome tutorial on Dependency Injection and The Castle Windsor IoC container.