自动属性验证

本文关键字:验证 属性 | 更新日期: 2023-09-27 18:04:29

有时,我有非常复杂的模型,有许多字符串属性需要在设置时进行验证,但是验证通常不会超过IsNotNullOrWhitespace

这通常会导致不必要的代码重复,所以我想知道是否有一种方法可以自动验证属性设置器的值,最好不需要任何额外的框架。

<

可能的解决方案/strong>

  • AOP(例如使用PostSharp)
  • <
  • 流利的验证/gh>数据注释

数据注释对我来说是最自然的方式,因为验证非常接近模型,而且因为它是。net框架的一部分,属性是可以的。但是,如果我使用MVC或序列化之外的模型,我必须使用验证器手动执行验证。因此,我必须在许多地方(存储库,api,服务)进行验证,如果我忘记在某个地方这样做,我的域规则可能会被打破。

AOP可能是完美的方式,但是c#中没有这样的东西,并且将我的领域模型与基础设施组件(如PostSharp或Ninject(拦截))紧密耦合是不允许的。

自动属性验证

Try NConcern AOP Framework

这个新的最小运行时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));
    }
}