中间层验证

问题描述:

我想对我的业务代码进行验证。我正在考虑2种方法来做到这一点。中间层验证

一,做验证我的阶级属性setter以下列方式现在

class Student{ 
    public string Name{ 
     get { return _name; } 
     set { 
      if (value.IsNullOrEmpty) throw exception ... 
     } 
    } 
} 

,这种方法的问题在于,验证代码运行每次名称被分配,我们可能并不需要,就像使用数据库填充数据一样。

两个,这是我愿意的话,把这些实体类的静态方法,像我使用的是静态方法,而不是一个实例方法

class Student { 
    public **static** void ValidateName(**string name**) { 
     if (string.IsNullorEmpty(name)) 
     { 
      throw ... 
     } 
     ... 
    } 

通知,像

class Student{ 
    public void Validate() { 
     // validation logic on instance properties 
     if (string.IsNullorEmpty(Name)) 
     { 
      throw ... 
     } 

     ... 
    } 

是因为我并不总是得到一个学生obj传入,我确实得到像字符串名称这样的基本类型通常是时间传递给一个方法,就像

public static FindStudentByName(string name) 
{ 
    // here I want to first do validation 
    Student.ValidateName(name); 

    // query DB 
    ... 
} 

如果我在学生的obj获得通过,那么当然我可以做

public static AddStudent(Student s) 
{ 
    // call the instance method 
    s.Validate(); 
} 

现在,我希望让事情变得很简单,所以我不想去的任何一个以下方法

  1. 在属性上使用属性,如[StringLength(25)]。

    一,因为这需要反思并影响性能,所以有一些技巧可以让性能降低,但我又想让它越简单越好。

    二,我希望我的网站能够在Medium Trust中运行。正如我所理解的那样,它需要完全信任。

  2. 使用任何验证块,如MS。企业库等在CodePlex上找到。

现在,我想你对这个意见,

是什么一些与我同去的办法潜在的问题?
与其他方法相比,此方法的执行效果会更好,更易读,更易于维护吗?

你如何在你的中间层进行验证?

谢谢一堆!

Ray。

选项二是实际上并没有强制验证,至少不是没有你手动调用验证。因此,您的对象的消费者可能会违反规则。

我个人会和你的第一个例子类似,因为它确保所有数据都是有效的。这是对数据库方面的额外检查,但从我注意到的情况来看,通常并不是什么大不了的事情。

+0

我想让消费者明确地调用验证,所以他们在验证发生时具有灵活性和控制权。但是,非常感谢你指出! – 2008-10-30 18:29:19

我与规则引擎,非常类似于一个written about here中间层执行域验证。朋友的项目使用类似于你在后一个例子中提出的方法,最终的结果是不可维护的(脆弱的,很难实现通用验证用户界面)。规则引擎方法是可维护的,因为它将所有验证和持久性规则本地化在一个组织良好的位置,并将每个规则作为一个完全成熟的类 - 但是暴露域类的验证类似于您所提议的。有些人喜欢动态编译,因此他们将它们存储在数据库中进行高级别的部署后配置;在我的情况下,我喜欢他们编译时间检查,所以有一个静态类暴露lambda表达式的规则定义。

我知道这是不是符合你想要做什么,而是问我会怎么做,并说其他的方法不是很简单就好像在说“你怎么能写出可靠的代码,我想保持简单,所以单元测试是不可能的。“对我而言,将每条规则视为自己的类是很好的,因为它更易于维护和记录,尽管实现起来更复杂。

你建议的做法似乎表明,一组验证不应该总是应用。没关系。我看到了很多我们想要的规则和验证,大多数情况下并不总是如此。所以,这个问题变成了'你想要什么时候应用这些验证'?

比方说,你有一些验证你总是想申请和一些你想验证只有当我不知道你要保存到存储(数据库)。 在这种情况下,应用的检查应始终存在于属性中(请参阅下面的更多内容),只有在您要保存到存储时才应用的检查应该位于方法中(可以按照'VerifyRulesForStorage'),它会在适当的时候被调用(例如在'SaveToStorage'方法的中间)。

有一两件事值得考虑,我认为,是当你有多个实体相同的验证你的风险承担的重复。无论是在属性中,还是在'VerifyRulesForStorage'方法中,很可能在许多类中的许多地方都有相同的检查(例如:String.IsNullOrEmpty,CheckItsANumber或CheckItsOneOfTheAcceptedValues等)。 当然,你可以通过继承来解决这个问题(例如你的所有实体都继承自实现每种类型检查的方法的基类),或者组合(可能是一种更好的方法,这样你的实体的类树就由其他驱动,更合适的考虑,例如:所有的实体都有一个Validator对象来实现所有这些检查)。无论哪种方式,你可能想要远离静态方法,如果你是测试驱动的(当需要时有方法),它们往往会产生有问题的情况。

在我们的系统,我们实际上有一个描述验证规则的元数据。该类的属性名称用于检索适当的元数据,然后告诉系统应用哪些规则。然后我们有一个验证器对象,通过工厂实例化适当类型的对象以实际执行验证(例如,我们有一个类实现了IsRequiredString规则,一个实现了IsNumber规则等等)。听起来很复杂,但在像我们这样的lrge系统中,这绝对是值得的。

最后,现成的,货架库出有可能是一个很好的选择。在我们的情况下,他们并不是因为我们的特殊要求 - 但总的来说......使用别人已经开发(并将支持)的车轮有利于构建自己的车辆(相信我,我喜欢在我重建车轮时可以......我只是说有些情况下每种方法都比另一种更好)。