Patterns-Based Silverlight Development – Part II – Repository and Validation

Introduction

In this post I will provide a brief overview of the Repository pattern, implement a Repository in our sample application, establish our server-side validation and add our test project.

Acknowledgements

Most of what you will see in this post follows very closely with the code ScottGu implemented in his NerdDinner tutorial. In fact, I would highly recommend reading that if you haven’t already. I will implement the repository, fake repository and validation using the implementations he laid out in that chapter. I am a big fan of ScottGu’s samples. I feel they are very effective in walking that delicate balance between simple to understand and useful.

I will deviate a bit from the Gu’s repository in order to implement the Pipeline pattern in the next post. Further, I will likely dedicate a post in this series to implementing Rhino Mocks for our MockRepository.

The major benefits of implementing the Repository pattern are twofold. First, it abstracts away the data persistence implementation. This gives you the ability to swap back ends out seamlessly. This can be especially advantageous today. You may well choose to swap out your back end database for a cloud-based data source. Second, and in my opinion more often relevant, is that it facilitates unit testing by providing a layer where you can inject a fake or mock back end. This allows you to test your code without having a dependence on a database. This will be very clear in the next post.

Implementing the Repository

Add the ITicketRepository Interface

We will use an interface to define the signature of our repository, so the first thing we need to do is to add the ITicketRepository class. Then we need to add all of the method signatures. Here it is:

There are a few things to notice here. The first thing is that we are delegating all of the work to the LINQ to SQL framework. That is why you don’t see much data access code here. Had I chosen to use the Entity Framework, we would have implemented it here, as well.

The second, and related, is that we are returning an IQueryable<T> from our fetch operations. When you compose a query with IQueryable, the clauses you add (where, select, order by, etc) are stored in an expression tree in memory. What is cool about this is you can continue to add expressions into the tree up until the time you fetch the data. For example, if a method calls GetTickets(), they will get an IQueryable<Ticket>. They could then add additional clauses into that query. For instance, they could add where clause that limits the tickets to those with a high severity level. We will take full advantage of this when we implement the Pipeline pattern in the next post. Why did I mention it here and not wait until I talked about the Pipeline pattern? I did so because, you might notice that for Tickets, there is only 1 fetch: GetTickets(). We don’t have a GetTicketsPage(int pageNum, int pageSize) that returns pages of tickets or a GetTicketsBySeverityLevel(SeverityLevel level). This is by design. We will implement that functionality in the Pipeline. As far as the Repository is concerned, all we need to do is return the IQueryable<T>.

Partial Classes and Partial Methods Described

Partial Classes

You may have noticed that the Ticket and the SeverityLevel class that the L2S (LINQ to SQL) designer created were marked as partial classes:

publicpartialclass SeverityLevel : …

publicpartialclass Ticket : …

Partial classes allow you to split the definition of a class into multiple files. At compile time, all of the files are compiled together. As far as the compiler is concerned, they may as well have existed in one file. This is a big help when working with designer-generated files. If you were to write some custom logic (say validation logic – hint, hint) directly in the generated file, what would happen when you made a change in the designer and the code was re-generated? Your hard work would be overwritten. However, if you were to add your code in another file in a partial class, it would remain. Nice.

Partial Methods

Partial Classes (or partial Structs for that matter) can contain partial methods. With a partial method, one Partial Class or Struct contains the signature of the method:

This again is very useful in designer-generated code. It is a great point of extensibility. A very cool thing about partial methods is that if there is no implementation, the method and any calls to it are pulled out at compile time. However, if there is an implementation, the call to that method will occur.

Server Side Validation

Create a Partial Class

As you might imagine, we are going to implement the server-side validation logic for our Ticket in a partial class. All you need to do is:

Create a class: Right-click the HelpDesk.Data project –> Add –> Class

Name it Ticket.cs

Mark it public partial

Implement our Validation

As I stated in the opening summary, I am going to use the simple validation implementation that ScottGu laid out in his NerdDinner tutorial (page 37). I will provide a bit of an overview here, but for a more thorough discussion see Scott’s tutorial. To start with, take a look at this code:

(For ease of reading, I used constants for the error message text instead of the preferred method of using resource files.)

Take a look at the GetRuleViolations method. This method can be called and it will return a collection of each and every RuleViolation (thanks to the yield return implementation). Each condition (if statement) will be evaluated in order. For each one, In the event the condition is true, the new RuleViolation will be provided to the enumerator (the method returns IEnumerable<RuleViolation>).

Inside of the method, I have added some sample validation checks. Clearly, this is not a complete list. Again, the goal of this series is not to build the complete application, rather, illustrate how to apply certain patterns. You can clearly see that you could write whatever custom validation you wanted here. In my examples, I made sure some properties weren’t null, I did some string length checking and made sure a date falls within a range (less than current). The important thing to realize is that if there are more than one violation, the complete list will be returned. The other thing to know is that anyone at anytime can call GetRuleViolations without the penalty of an exception being thrown if there are any violations.

The IsValid helper method simply returns true if there are any rule violations. Again, this can be called without fear of an exception.

The last method is the OnValidate partial method. As described earlier, the OnValidate signature was defined in the Ticket partial class that the L2S designer generated. Because we have added the implementation in our Ticket partial class, the method will be called by the LINQ to SQL framework prior to persisting any data. This gives us a chance to validate the data (thus the name). We simply call our IsValid method. If it is not valid (there is at least one RuleViolation), we throw a ValidationException. This is a slight deviation from what the Gu did in NerdDinner.com. he threw an ApplicationException. ValidationException is a simple class that implements Exception (see below). You will see why I throw a ValidationException when I get to the post on implementing our WCF services.

Testing our Validation Logic

Well, we have implemented our Repository and our server-side validation logic for Tickets (at least some validation logic). The next thing I want to do is to add a Test project and add some methods that test our validation logic. Again, I’m only going to add a couple which should be enough to illustrate the process.

As you can see, my method names are very verbose. This is by design. When you have a bunch of tests, it is nice to simply look at the name of a failed test and know what is wrong. Because we are testing the validation logic, we are able to simply new up a new Ticket and set (or fail to set) the appropriate properties that will define our tests. We don’t need to go through the Repository (yet).