non*_*ot1 2 c# validation interface
我有几个实现某个接口的类.
在接口而不是实现级别,有没有办法定义数据验证规则?
如果没有,那么从特定类中分解数据验证规则的建议模式是什么?(编辑:在我的情况下,我想避免使用抽象基类来实现验证.)
谢谢
我会将验证逻辑分成另一个类.例如,如果你的界面是IFoo你有FooValidator一个Validate(IFoo foo)方法.这将执行与IFoo围绕验证的业务规则分开.分离意味着:
IFooIFoo这个示例实现使用了一个ValidatorBase您最初不需要使用的抽象类,我过早地优化了它: - $.
interface IFoo
{
int Age { get; }
string Name { get; }
}
class Foo : IFoo
{
public int Age { get; set; }
public string Name { get; set; }
}
abstract class ValidatorBase<T>
{
public class Rule
{
public Func<T, bool> Test { get; set; }
public string Message { get; set; }
}
protected abstract IEnumerable<Rule> Rules { get; }
public IEnumerable<string> Validate(T t)
{
return this.Rules.Where(r => !r.Test(t)).Select(r => r.Message);
}
}
class FooValidator : ValidatorBase<IFoo>
{
protected override IEnumerable<ValidatorBase<IFoo>.Rule> Rules
{
get
{
return new Rule[] {
new Rule { Test = new Func<IFoo,bool>(foo => foo.Age >= 0), Message = "Age must be greater than zero" },
new Rule { Test = new Func<IFoo,bool>(foo => !string.IsNullOrEmpty(foo.Name)), Message = "Name must be provided" }
};
}
}
}
static void Main(string[] args)
{
var foos = new[] {
new Foo { Name = "Ben", Age = 30 },
new Foo { Age = -1 },
new Foo { Name = "Dorian Grey", Age = -140 }
};
var fooValidator = new FooValidator();
foreach (var foo in foos)
{
var messages = fooValidator.Validate(foo);
if (!messages.Any()) Console.WriteLine("Valid");
else foreach (var message in messages) Console.WriteLine("Invalid: " + message);
Console.WriteLine();
}
}
Run Code Online (Sandbox Code Playgroud)
运行程序会得到以下结果:
有效
无效:年龄必须大于零
无效:必须提供姓名无效:年龄必须大于零