Recomiendo crear una interfaz IValidator y luego crear múltiples validadores diferentes que manejen diferentes escenarios. Aquí está un ejemplo:
public interface IValidator {
bool CanValidateType(string type);
bool Validate(string input);
}
El método CanValidateType() podría ser un poco más complejo, pero espero que se entiende la idea. Básicamente identifica si el validador puede manejar la entrada suministrada. Aquí hay un par de implementaciones:
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 */
}
}
Ahora que va a utilizar la inyección de constructor para inyectar la dependencia en su clase:
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 */
}
}
El CanValidateType es muy útil cuando se tiene una clase que puede utilizar varios validadores. En este escenario, transfiere una lista o una matriz de validadores al 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;
}
}
A continuación, tendría que pasar en la instancia requerida del validador (s) a sus clases de alguna manera. Esto se hace a menudo con un contenedor IoC (como Castle Windsor) o hágalo usted mismo.
IValidator emailValidator = new EmailValidator();
IValidator urlValidator = new UrlValidator();
SomeSimpleClass simple = new SomeSimpleClass(urlValidator);
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator });
El código anterior se vuelve tedioso a hacer por su cuenta, es por eso que los contenedores IoC son tan práctico. Con un contenedor IoC que puede hacer algo como lo siguiente:
SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();
Todo el mapeo de interfaces se realiza en el app.config o web.config.
Aquí está an awesome tutorial en Dependency Injection y el contenedor Castle Windsor IoC.
¿Qué más hacen las clases? En aras de la claridad, una clase debería tener un único propósito. La solución de FrustratedWithFormsDes sigue este principio. – outis