我正在处理来自MSMQ的消息。

对于每个消息,有十个步骤,例如:


验证日期
VerifyPatientInformation
验证临床信息


如果三个步骤中的任何一个都失败了,我想抛出这个信息。

有人可以指出SOLID示例来演示此主体吗?我不确定如何构造我的课程。

例如

public class VerifyDates()
{
    private validateSomething ValidateSomething();

    public VerifyDates()
    {
        validateSomething = new ValidateSomething();
    }

    public bool Verify()
    {
        validateSomething.IsValid();
    }

}


假定VerifyDates()是我的处理逻辑的一部分,我是否应该在bool标志类中添加一个公共字段,该标志返回是否继续处理?

也许我应该添加一个接口IHasFlag,其中处理逻辑中使用的每个类都有一个标志,我在末尾检查该标志以查看是否继续进行消息处理?

处理消息会像这样

public void ProcessMessages()
{
  var verifyDates = new VerifyDates();
  if(!verifyDates.IsValid)
  {
    return;
  }
  //continue processing
  //but every step of the process I would need to check IsValid for that specific class
}


您如何抽象顺序过程中每个步骤的成功/失败?

最佳答案

您可以使用流利的API。类似于以下内容:

public interface IFluentValidation<T>
{
     bool IsValid { get; }
     T ObjectToValidate { get; }
}

internal class FluentValidation<T>: IFluentValidation<T>
{
    public bool IsValid { get; }
    public T ObjectToValidate { get; }

    public FluentValidation(bool isValid, T target)
    {
        Debug.Assert(target != null);
        IsValid = isValid;
        ObjectToValidate = target;
    }
}


现在构建以下扩展方法:

public static IFluentValidation<T> ValidateBy<T>(this T target, Predicate<T> validator)
{
     if (target == null) throw new ArgumentNullException(name(target));
     if (validator == null) throw new ArgumentNullException(name(validator));

     if (validator(target))
        return new FluentValidation<T>(true, target);

     return new FluentValidation<T>(false, target);
}

public static IFluentValidation<T> AndBy<T>(this IFluentValidation<T> target, Predicate<T> validator)
{
     if (validator == null) throw new ArgumentNullException(name(validator));

     if (!target.IsValid)
        return target;

     if (validator(target.ObjectToValidate)
        return target;

     return new FluentValidation<T>(false, target.ObjectToValidate);
}


如果要返回已验证的对象而不是OrBy,则实现AndFinallyBy作为IFluentValidation<T>是简单的。

您将像这样使用它:

 var validated = myObject.ValidateBy(t => //whatever needs to checked t.ObjectToValidate.DateIsValid)
                         .ThenBy(t => ... //whatever needs to be checked t. ObjectToValidate.PatientIsValid)
                         .ThenBy(t => ... //t.ObjectToValidate .ClinicalInformationIsValid)
                         .IsValid;


您还可以对此进行更多修饰,并在每个验证步骤中添加可选的自定义错误消息。 public static IFluentValidation<T> AndBy<T>(this IFluentValidation<T> target, Predicate<T> validator, Func<T, string> failureMessageProvider = null)并将相应的属性string ValidationFailedMessage { get; }添加到IFluentValidation

10-04 13:01