我正在尝试编写一个可以链接的通用方法参数验证功能(流利的接口)以附加越来越多的验证/检查,例如:
public void SomeMethod(User user, string description)
{
ParameterHelper
.Create(() => user)
.RejectNull();
ParameterHelper
.Create(() => description)
.RejectNull()
.RejectEmptyString();
// now this would be luxurious
ParameterHelper
.Create(() => new { user = user, desc = description })
.RejectNull(o => o.user)
.RejectNull(o => o.desc)
.RejectEmptyString(o => o.desc);
}
我想在使用它们之前使用这个帮助类来测试某些值的方法参数(大部分时间null
都会被测试)。
现状_
我首先开始编写静态辅助类,但没有使用如下Create()
方法:
public static class ParameterHelper
{
public static void RejectNull(Expression<Func<T>> expr)
{
if (expr.Compile()().Equals(default(T)))
{
MemberExpression param = (MemberExpression)expr.Body;
throw new ArgumentNullException(param.Member.Name);
}
}
}
但这不允许链接。这就是为什么我创建了一个Create()
方法来返回可以被链式扩展方法使用的东西。
问题
- 我想避免多次
Compile()
调用,所以基本上我的Create()
方法应该返回Func<T>
,而拒绝方法应该是Func<T>
. - 如果我
Create()
确实返回Func<T>
,我没有机会读取应该提供给各种异常的参数名称(使用MemberExpression
)。 - 如果我返回
Expression<Func<T>>
,我将不得不调用Compile()
每个Reject
扩展方法。
问题
- 是否有已经进行这种链接的 C# 库?
- 如果没有,你建议如何做到这一点?来自网络的任何示例都将受到热烈欢迎。
附加说明
我应该指出,复杂/长验证调用代码在这里不是一个选项,因为我当前的验证是这样完成的:
if (user == null)
{
throw new ArgumentNullException("user");
}
或者
if (string.IsNullOrEmpty(description))
{
throw new ArgumentNullException("description");
}
它有两个主要缺点:
- 我一遍又一遍地重复相同的代码行
- 它使用魔术字符串
因此,验证应按照上述所需场景中的每次检查使用一个衬垫来完成。