State vs Interception Validation vs Code Contracts

25Jan09

As ValidationAspects is gaining awareness in the .net community I have been asked several times questions regarding its use at a conceptual level, in particular the two modes of validation offered (State & Interception), and how VA (ValidationAspects) differs and overlaps with Code Contracts.

I think the idea of what “Validation” is depends on your viewpoint of whether a model is permitted enter an invalid state. Typically for existing validation frameworks, models are updated with a value that can put the model into an invalid state. The model would then be validated which would check if any of the properties had an invalid value. I call this State Validation. Using aspects to intercept the method or property setter, the setting value can be validated prior to updating the model. The update fails if the value is invalid. I call this Interception Validation. I see Code Contracts pre-conditions as providing the same feature as Interception Validation – the body of the method/property setter will not execute unless all contracts are met.

But can you call Code Contracts pre-conditions Validation? Maybe – in the following example, for Interception Validation you could take the view that you are validating the directoryPath value. So code-contracts are validation but on the value and not the object. If you don’t buy this don’t worry – I want to compare functionality rather than terminology.

public class MyModel
{
  public void Export( string directoryPath )
  {
    Contract.Requires( Directory.Exists( directoryPath ));
    ....
  }
}

OK, so how would you implement this with VA and what do you gain?

[Validate]
public class MyModel
{
  static MyModel()
  {
    // put this code anywhere - it doesn't have to be in the model!
    typeof(Utilities).GetMethod("Export").GetParameters()[0].AddValidation<string>((v, i) => {
      if (!Directory.Exists(v))
        throw new ValidationException(string.Format("Directory {0} does not exist.", v));});
  }

  public void Export([NotNullOrEmpty] string directoryPath )
  {
    ....
  }
}

We’ve added the Validate attribute. This is a PostSharp attribute that will apply VA interceptors to the properties and methods of MyModel. When Export(…) is invoked, the VA interceptor will invoke all VA validation registered to the method and to its properties. We have two validators registered to the directoryPath parameter. The first is applied by an attribute, the second is a lambda expression registered on the parameter. We’ve placed the expression registration in the static constructor but this could be done anywhere AND at any time. VA allows for programmatic replacement and augmentation of validation applied to Types, Properties, Methods, and Method Parameters. This is a very important difference from Code Contracts. We’ve hardcoded validation/pre-conditions but we can change these at runtime.

Why is this useful? Because validation extends beyond simple code contracts into business rules validation – custom/dynamic validation to reflect changing business goals or possibly different deployments. Let’s say you build an Invoice Management system for two different customers, and the system uses an Invoice domain model with an InvoiceId property. For customer A, their business rules dictate that a valid InvoiceId must be an 8-digit numeric, where customer B’s business rules dictate that a valid InvoiceId is 4 digits followed by the invoice’s CustomerId. In code we can declare using a validation attribute that an InvoiceId must not be null or empty – this is one of our model rules. At runtime we augment this validation with the customer’s business rules validation via configuration. Using this approach we can augment domain model validation rules for different deployments. Now when the InvoiceId is set by some means, say UI data entry, and the value fails the business rules validation, a validation exception is thrown to ensure that the Invoice does not enter an invalid state and the user is notified via WPF/asp.net MVC.

So there is an overlap between Code Contracts and Interception Validation but also several important benefits for both approaches. Of course you can always switch off Interception Validation if you prefer and use State Validation and Code Contracts. In the latest drop of VA, the interception feature has been moved out to a separate assembly so there’s no need for the Validate attribute or dependecy on PostSharp.

For a short introduction to ValidationAspects please see this post. VA is open-source and available on codeplex.

Advertisements


5 Responses to “State vs Interception Validation vs Code Contracts”

  1. Hi,

    can I combine this two validation modes? Can I have interception rules for reporting typos in the moment (or adhoc) and state validation just before commiting all changes (and persist the object in the very next moment)?

    Are this rules also available when working with a business object (well prepared for ValidationAspects) in plain code and not attached to some UI?

    With best regards

    Gerhard

  2. 2 Mike

    Hi Gerhard,
    You can enable both Interception and State validation. These modes refer to Property validation and are both enabled by default. Interception validation results in ValidationExceptions thrown when a property is (attempted to be) set with an invalid value. Your UI would handle this exception. Interception Validation will prevent the model from becoming invalid. With State Validation enabled, the property validators would also be called when you invoke model.Validate(). Exceptions are not thrown is this case but returned as a ValidationResult. model.Validate() will also invoke validators applied to the model’s Type and base Types.

    When hooked up to a UI, Interception Validation would be used for validating the user’s input data, and you could then call model.Validate() (via a Save button) to validate the state of the model.

    VA works on the model – how a UI handles validation reported by VA is dependant on the UI. There are some examples of integration with WPF and asp.net MVC (using xVal) on the blog and I think also some info of how to integrate with WPF Model-View-ViewModel on a codeplex discussion thread. Let me know if you ned any more info.

  3. This post will assist the internet users for building up new weblog or even a weblog from start to end.

  4. Everything is very open with a clear explanation of the issues.

    It was definitely informative. Your website is extremely helpful.
    Many thanks for sharing!

  5. Good post. I absolutely appreciate this site. Continue the good
    work!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: