C# 自动属性验证

C# 自动属性验证,c#,validation,ninject,aop,postsharp,C#,Validation,Ninject,Aop,Postsharp,有时,我有很多需要在设置时验证的字符串属性的非常复杂的模型,但是验证通常不会超过IsNotNullOrWhitespace 这通常会导致不必要的代码重复,因此我想知道是否有一种方法可以自动验证属性setter值,最好不用任何额外的框架 可能的解决方案 AOP(例如,使用PostSharp) 流畅验证 数据注释 对我来说,数据注释是最自然的方式,因为验证非常接近模型,而且由于它是.Net Framework的一部分,所以属性也可以。但是,如果我在MVC或序列化之外使用模型,我必须使用验证器手动

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

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

可能的解决方案

  • AOP(例如,使用PostSharp)
  • 流畅验证
  • 数据注释
对我来说,数据注释是最自然的方式,因为验证非常接近模型,而且由于它是.Net Framework的一部分,所以属性也可以。但是,如果我在MVC或序列化之外使用模型,我必须使用验证器手动进行验证。因此,我必须在很多地方(存储库、API、服务)进行验证,如果我忘记在某个地方进行验证,我的域规则可能会被打破

AOP可能是一种完美的方式,但是C中没有直接的AOP,而将我的域模型与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());
            }
        });
    }
}
进入另一个程序集(验证和域之间的链接

//attach validation to Customer class.
foreach (var property in typeof(Customer).GetProperties())
{
    if (property.IsDefined(typeof(Email), true))
    {
        Aspect.Weave<Validation>(property.GetSetMethod(true));
    }
}
//将验证附加到客户类。
foreach(typeof(Customer.GetProperties()中的var属性)
{
if(property.IsDefined(typeof(Email),true))
{
Weave(property.GetSetMethod(true));
}
}

何时需要进行验证?当@setter时,是的,您应该使用AOP。您可以查看Fody()这是免费的。也许这减少了你对耦合到基础设施组件的担忧。不管怎样,我不得不问:你愿意拥有更多的代码并为其支付费用,还是愿意一次又一次地维护它,或者你愿意依赖基础设施组件,加快开发速度并减少出现错误的机会?什么是基础设施组件什么不是呢?你是依靠VS还是使用(任何)文本编辑器,因为耦合太麻烦你了?;-)
//attach validation to Customer class.
foreach (var property in typeof(Customer).GetProperties())
{
    if (property.IsDefined(typeof(Email), true))
    {
        Aspect.Weave<Validation>(property.GetSetMethod(true));
    }
}