Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I perform a check to see if a value already exists in the database when performing validation in MVVM using IDataErrorInfo?

Getting started with all this MVVM stuff, I was following this post by Josh Smith that talks about an approach to validation while using MVVM. The example is simple, and I began to wonder how I would use it in my own application.

I have, in my BLL, a BookInfo class that implements IDataErrorInfo to report invalid values such as "published date can't be in the future" or "number of pages can't be negative". Then my AddBookViewModel would check the state of the newly created BookInfo, see that errors exist, and the AddBookView will display a red blob next to the appropriate TextBox. That stuff is straightforward, just like in the example in the post.

Now my BookInfo class also holds a list of author IDs. On addition of a new BookInfo to my database, I need to check if those author IDs already exist.

Should this check be done in my BookInfo class? If so, then I would have to pass in my BLL's AuthorManager object to BookInfo's constructor, since the former would contain methods such as CheckIfExists(int authorID).

Is this the recommended approach? What if there are a lot of records in the DB? Dynamically checking would affect performance?

On the other hand, it would seem a bit messy to perform some checks in the BookInfo class and some elsewhere... especially when all those checks can be categorized into the same group... ie. making sure a newly created BookInfo object is valid. Or maybe I'm wrong since I don't really have experience to make proper judgement.

Some guidance?

like image 518
ForeverLearnNeverMaster Avatar asked Apr 15 '11 14:04

ForeverLearnNeverMaster


2 Answers

I wouldn't do this. I would keep the validations done 'inside' IDataErrorInfo simple and contextless. Any validations that depend on context, such as cross-entity validations and validations that are dependent on a database, do that validation when you save the changes.

Trying these more complex context based validations in IDataErrorInfo will be error prone and often impossible. It is often impossible to do this reliably without a context.

I've written a blog post about this. While it is written in the context (no pun intended) of the Validation Application Block, it talks about the general problem of context based validation. It might be helpful. Here it is.

like image 52
Steven Avatar answered Nov 03 '22 22:11

Steven


I agree with Steven that you should perform the server-side validations when attempting to save the data.

Another reason for this is network latency. Since WPF's support for IDataErrorInfo uses input events to determine when properties are validated, and results in a blocking/synchronous call to your VM object, the use of IDataErrorInfo has a direct impact on the responsiveness of the UI. You cannot begin an async call to your database to perform the validation and then dispatch validation errors to the UI thread when your network call completes. You would have to make a blocking call to your DB to get the result, which could wreak havoc on the UI thread while it waits for the call to return.

I hope someday WPF gets Silverlight's fancy new INotifyDataErrorInfo interface, which allows for the async validation scenario I described above.

like image 33
Josh Smith Avatar answered Nov 03 '22 22:11

Josh Smith