现在,有许多Fluent实现可以与Lambdas一起工作,从而完成非常整洁的事情。我想把我的大脑包起来,这样我就可以开始创建其中的一些东西,但是我还没有找到我的大脑可以理解的解释。

考虑这个简单的人员验证器示例

public class PersonValidator : IValidator<Person>
{
     public PersonValidator()
     {
          AddRule(p => p.FirstName).CannotBeNull().CannotBeBlank();
          AddRule(p => p.LastName).CannotBeNull().CannotBeBlank();
     }

     public List<ValidationResult> Validate(Person p)
     {
         // pseudo...
         apply all rules specified in constructor, return results
     }
}

我已经设法使用我的Validator上的方法来完成所有这些工作的一部分...
public ValidationResult<T,TProp> AddRule<T,TProp>(Func<T,TProp> property)
{
    ... not sure what to do here.  This method gives me the ability to use the lambda
    ... for specifying which properties i want to validate
}

然后,我可以创建用于扩展CanalBeNull和CannotBeEmpty的IValidator的扩展方法。

所以看来我有问题的上半部分和下半部分,但是我不确定如何将它们组合在一起。

寻找有意义的解释...我想“得到它”。 :)

最佳答案

流利接口(interface)的关键是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;
    }
}

尽管以上内容演示了如何创建流畅的界面,但从长远来看,在这种特殊情况下,我真的不知道它能为您带来什么。为了方便似乎仅在内部用于具体验证器的流畅接口(interface),您将代码的复杂性提高了相当数量,而没有真正为验证器的使用者提供有用,流畅的接口(interface)。我认为您可以通过为需要执行验证的开发人员提供流利的验证框架,而不是提供用于创建具体验证器的流利框架来获取更多值(value)。

10-04 15:16