我正在处理来自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