开发者

What would you choose, a slight performance hit or some additional complexity?

We are using a validation framework (something we have cooked up ourselves) which allows us to do validation assertions on objects.

string Validation<T,U>(T obj, Func<T,U> selector, Validations.IsNotNull,
                       string failureMessage) 
       {
           var propertyToBeValidated = selector(obj);
           // Do validation here, if it fails, return failure message
       }

The problem with this is:

  • The message is mandatory. We cannot auto generate a meaningful message looking at the selector.

The other option is to change the signature of the above method to:

string Validation<T,U>(T obj, Expression<Func<T,U>> selector, 
                       Validations.IsNotNull, string failureMessage = null) 

In this case the failure message is optional and we can get the property name from the expression tree.

However, this requires开发者_运维知识库 an Expression.Compile before the selector can be invoked and slows down things by 3 orders of magnitude. As of now the messages are mandatory but as the validations are somewhere else, refactoring requires changing the validation messages too.

What would you suggest:

  • Change signature and accept expressions. Cache the compiledd expressions if need be and auto generate the messages. Is a message is provided, use that instead.
  • Changing messages by hand is an acceptable overhead as you have a good test coverage. Leave the signature as is and avoid the additional complexity and the performance hit.

Edit: We are using this validation framework accross multiple layers. In out controllers for validating input parameters, in our services for validating incoming requests and in our integration tests for validating state of objects after some operations. The cost of expression.Compile is insignificant compared to some of these costs, but not insignificant compared to datbase access, etc. Thanks


Why do you have to choose? You could just have both

string Validation<T,U>(T obj, Func<T,U> selector, Validations.IsNotNull,
                        string failureMessage)

and

string Validation<T,U>(T obj, Expression<Func<T,U>> selector,
                          Validations.IsNotNull)

as overloads. That way you only take the perf hit when there's no message and you can't cache the compiled lambda.


Well, I think comparing this to db calls is like comparing apples and oranges. And it is likely that per object this code will get called multiple times, imagine a class decorated with this for parameters, private members, and an object of this type getting created in a for loop :D..hope what I am talking makes sense, because I have not really done any coding with generics or compiling expressions and the like..but I guess what you do is try to guess to get to the stuff being validated..by analyzing the expression tree.

Personally, I think it better to keep the message mandatory, how about the possibility of providing two separate methods (is polymorphism) supported with a well documented caveat when messages are not supplied...


We concluded that for us it made the most sense to use an Expression. The overhead of the DB and WS calls was far greater than this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜