Ключом к свободным интерфейсам является то, что такие методы, как CannotBeNull () и CannotBeBlank (), возвращают текущий экземпляр (то есть this). Если вы хотите, чтобы ваш метод AddRule был «плавным», вместо того, чтобы возвращать ValidationResult, вам нужно вернуть текущий экземпляр IValidator. Ваши методы расширения также должны возвращать экземпляр IValidator, который они расширяют.
Я думаю, что ваша точная реализация может быть немного более сложной, и, надеюсь, приведенный ниже пример даст некоторое представление. То же общее правило, однако ... верните "this", чтобы создать свободный интерфейс:
interface IValidator<T>
{
IValidatorRule<T, TProp> AddRule<TProp>(Func<T, TProp> property);
}
interface IValidatorRule<T>
{
T instance { get; }
string PropertyName { get; }
ValidationResult Apply(T instance);
}
public static IValidatorAugmentorExtensions
{
public static IValidatorRule<T> CannotBeNull(this IValidatorRule<T> rule)
{
// ...
return rule;
}
public static IValidatorRule<T> CannotBeBlank(this IValidatorRule<T> rule)
{
// ...
return rule;
}
}
Вышесказанное можно использовать так:
public class PersonValidator: IValidator<Person>
{
public PersonValidator()
{
AddRule(p => p.FirstName).CannotBeNull().CannotBeEmpty();
AddRule(p => p.LastName).CannotBeNull().CannotBeEmpty();
}
public List<ValidationResult> Validate(Person p)
{
List<ValidationResult> results = new List<ValidationResult>();
foreach (IValidatorRule<Person> rule in rules) // don't know where rules is, or what the AddRule method adds to...you'll need to figure that out
{
results = rule.Apply(p);
}
return results;
}
}
Хотя вышеприведенное демонстрирует, как создать свободный интерфейс, я действительно не знаю, что он покупает в долгосрочной перспективе в данной конкретной ситуации. Для удобства свободного интерфейса, который, кажется, используется только внутри конкретных валидаторов, вы значительно увеличили сложность своего кода, не предоставляя полезного, свободного интерфейса пользователям ваших валидаторов. Я бы подумал, что вы могли бы получить больше пользы, предоставляя разработчикам, которым необходимо выполнять проверку, свободную среду проверки, а не предоставляя свободную среду для создания конкретных средств проверки.