Si consiglia di creare un'interfaccia IValidator quindi creare più validatori diversi che gestiscono diversi scenari. Ecco un esempio:
public interface IValidator {
bool CanValidateType(string type);
bool Validate(string input);
}
Il metodo CanValidateType() potrebbe essere un po 'più complesso, ma spero che si ottiene l'idea. In pratica identifica se il validatore può gestire l'input fornito. Qui ci sono un paio di implementazioni:
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 */
}
}
Ora si userà l'iniezione del costruttore per iniettare la dipendenza nella tua classe:
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 */
}
}
Il CanValidateType è particolarmente utile quando si dispone di una classe che può utilizzare più validatori. In questo scenario si passa in una lista o una matrice di validatori al costruttore.
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;
}
}
Si sarebbe quindi dovuto passare l'istanza richiesta del validatore (s) per le vostre classi in qualche modo. Questo è spesso fatto con un contenitore IoC (come Castle Windsor) o fai da te.
IValidator emailValidator = new EmailValidator();
IValidator urlValidator = new UrlValidator();
SomeSimpleClass simple = new SomeSimpleClass(urlValidator);
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator });
Il codice di cui sopra diventa noioso da fare da soli, questo è il motivo per cui i contenitori IoC sono così a portata di mano. Con un contenitore CIO si può fare qualcosa di simile al seguente:
SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();
Tutta la mappatura delle interfacce è fatto nel vostro app.config o web.config.
Ecco an awesome tutorial su Dipendenza dell'iniezione e il contenitore Windsor Castle IoC.
Cos'altro fanno le lezioni? Per motivi di chiarezza, una classe dovrebbe avere un unico scopo. La soluzione di FrustratedWithFormsDes segue questo principio. – outis