有时,我有非常复杂的模型,其中包含许多需要在设置时验证的字符串属性,但是验证通常不会比 IsNotNullOrWhitespace 更进一步。
这通常会导致不必要的代码重复,所以我想知道是否有一种方法可以自动验证属性 setter 值,最好不需要任何额外的框架。
可能的解决方案
- AOP(例如使用 PostSharp)
- 流畅的验证
- 数据注释
数据注释对我来说是最自然的方式,因为验证非常接近模型,而且由于它是 .Net-Framework 的一部分,所以属性没问题。但是,如果我在 MVC 或序列化之外使用模型,我必须使用验证器手动进行验证。所以我可能必须在很多地方(存储库、API、服务)进行验证,如果我忘记在某个地方进行验证,我的域规则可能会被破坏。
AOP 可能是完美的方式,但是 C# 中并没有这样的东西,将我的领域模型与 PostSharp 或 Ninject(拦截)等基础设施组件紧密耦合是一个禁忌。
最佳答案
这个新的最小运行时 AOP 框架(我积极致力于此)可以帮助您通过 AOP 管理验证,而无需耦合您的域程序集。
在您的验证程序集中,定义您自己的验证属性以及如何验证它。
定义/识别电子邮件的自定义属性
[AttributeUsage(AttributeTargets.Property)]
public class Email : Attribute
{
//validation method to use for email checking
static public void Validate(string value)
{
//if value is not a valid email, throw an exception!
}
}
检查代码契约的验证方面
//Validation aspect handle all my validation custom attribute (here only email)
public class EmailValidation : IAspect
{
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
yield return Advice.Before((instance, arguments) =>
{
foreach (var argument in arguments)
{
if (argument == null) { continue; }
Email.Validate(argument.ToString());
}
});
}
}
你的域程序集
public class Customer
{
[Email]
public string Login { get; set; }
}
进入另一个程序集(验证和域之间的链接
//attach validation to Customer class.
foreach (var property in typeof(Customer).GetProperties())
{
if (property.IsDefined(typeof(Email), true))
{
Aspect.Weave<Validation>(property.GetSetMethod(true));
}
}
关于c# - 自动属性验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23781720/