OpenDBDiff – OS tool for SQL Server Schema Comparisons
I can’t think of the last project I was involved in where I didn’t have to do schema comparisons between differing databases to generate diff scripts. Sometimes I have a local copy of the DB on my laptop that I need to synch with a dev database. Other times I have to create the scripts that we will use to deploy schema changes between dev and staging. Sometimes I just want to see if there are any differences between my local DB and another to see why some tests aren’t passing. Regardless, I find myself consistently managing this task..
There are a variety of tools available to help with this task: RedGate and Data Dude to name a couple. Recently a couple of colleagues put me on to OpenDBDiff. I say a couple of colleagues because the lot I work with tell me about “helpful” OS tools and projects almost daily. When I hear 2 or more folks use the same tool, my antennas go up.
OpenDbDiff is an open source database schema comparison tool for SQL Server 2005 / 2008. In my opinion, the beauty of OpenDBDiff is the simplicity. Without looking at ANY documentation, you can do a full schema comparison between 2 databases, choose the object types you want to script and generate schema comparisons. Let’s have a look:
Getting Started
Here are the simple steps to get started with OpenDBDiff:
- Download OpenDBDiffl Simply go to the codeplex site and click download. You will download a zip file.
- Unzip the contents into a folder in your Tools directory (or wherever you keep your tools).
- Run DbDiff.exe. It is that easy…
The Demo
I have both SQL Server and SQL Server Express running on my box and this will do for our simple demo. On my SQL Server instance, I have a database called HelpDeskDB that I used in my Entity Framework Training Series. The first step is for me to is to create an empty HelpDeskDB on my express instance and spin up DBDiff. I’ll use it to copy the schema to my new database. Here is a screenshot:
The Options gives you typical SQL Compare options. Here is a view of the filter options:
Once you press “Compare”, you can see a summary of the differences in the left hand list box:
Or you can have a look at the sync script:
In my case, I am going to copy the script to the clipboard and run it on my target database to sync them.
Syncing Changes
With that done, I now have 2 databases with the same schema. Next, I want to show you an example of syncing changes between 2 databases. The first thing I will do is make a schema change to my new database. I am going to add a non-nullable** column to my Contacts table. Here is the change:
Now, I will reverse the databases in OpenDBDiff, setting my “new” database (with the updated schema) on SqlExpress as the source and my original database as the destination and press “Compare”. Here is the SQL Script that was generated (omitting the dropping and creating constraints for brevity sake):
As you can see, the SQL generated does the following:
- (not shown here) Drop the Constraints
- Creates a temp table with the new, non-nullable column
- Inserts the data from the original table into our new table (it is even smart enough to default the datetime with GetDate())
- Drop the original table
- Rename the new table
- (not shown here) Create the Constraints
Conclusion
As you can likely see, OpenDBDiff is a handy tool for your toolbox. It is open source, easy to use and does a great job at schema comparisons.
**Note: you might not want to introduce a new column as non-nullable in one release. This is a topic for a future post.
Do You NCrunch Yet?
If you haven’t heard of NCrunch, you are in for a great surprise. Over the past few years, a friend and colleague of mine, Remco Mulder, has been slaving away on NCrunch. What is NCrunch? In my opinion, it is the most powerful Visual Studio plugin available. It is designed to help developers with TDD and automated testing in general. The plug-in runs automated tests in the background while a developer writes code, and shows code coverage inline in real time as this code is written.
You may be wondering if you read that correctly. Does NCrunch run your tests while you are writing code? Yes it does. NCrunch sandboxes the entire process of building, executing and testing a transient snapshot of a .NET solution – without a developer even needing to save their code to the hard disk. Feedback and code coverage from the tests is presented tidily and unobtrusively alongside the source code with any thrown exceptions or test failures shown inline. Let’s have a look at a snapshot of one of my projects in VS 2010 (with NCrunch).
Notice the green dots on the left hand side. They tell me that the line of code next to it is covered by at least one test and all of the tests covering that line are passing. If it wasn’t covered, the dot would be black. Let’s see what it would look like for a failing test. I am going to change the last line in IncrementIndex() to decrement the index by one instead of increment it. Have a look:
As you can see, NCrunch is now letting me know that all the lines of code with red dots are covered by failing tests. By the way, all I did was to replace the “+” with a “-“. I did not compile, or even save my change.
I have some options now. If I click on a red dot, the following context menu shows up:
From here, I can see the tests that are covering the line. I can navigate to the specific tests by simply clicking on it in this menu.
If I right click on a red dot, the following menu shows up for me:
As you can see, I can run the tests that are covering the code (if I don’t believe NCrunch), I can choose to ignore any failing tests (shame on me) or I can pin them to the tests window.
Why use NCrunch?
Some of you, like me, practice TDD. Others may not. However, all of you should be writing automated tests! NCrunch helps both groups. Before I started using NCrunch, I never realized how disruptive running my unit tests was. It was just a way of life. Write a test… Stop… Run my test… Stop… Write Code to make test pass… Stop… Run my test… Refactor… Repeat… Now, I almost never run my unit tests manually. They are always running behind the scenes. I don’t need to stop developing and do a mental context shift. I’m guessing that this saves me at least an hour of productivity a day.
The other beauty of NCrunch is the real-time feedback you get. First of all, it is very apparent where you have holes in your test coverage. Secondly, you know immediately if the code you are writing broke any tests. The nice thing is that you get this feedback when you are most prepared to address the issue. The code is fresh in your mind (you just wrote it)
Where do you get it and how much?
You can download NCrunch at www.ncrunch.net. Right now, it is in a beta state and Remco has decided to make it freely available in exchange for feedback from the .NET community. Good luck and get NCrunching.
Using the Builder Pattern in tests
One of the most painful parts of writing tests is creating test data. Whether you use mocking frameworks or write your own fakes, one thing is constant… you will find yourself creating object instances over and over. You have to create inputs to the methods you are testing, return values for stubs or mocks, data in fake repositories, etc. The Builder Pattern can greatly ease this burden. In this post, through example, I will show how.
The Scenario
The following is a simplified version of Coupon and Order types from DevEducate.com:
public class Coupon
{
public int Id { get; private set; }
public string CouponCode { get; set; }
public decimal Discount { get; set; }
public DateTime ExpirationDate { get; set; }
public string Description { get; set; }
public int ExecuteMaxTimes { get; set; }
public decimal MinimumOrderAmt { get; set; }
public CouponType CouponType { get; set; }
…
}
public enum CouponType
{
PercentOffOrder = 1,
AmountOffOrder = 2
}
public interface IOrder
{
decimal SubTotal { get; }
}
public class Order : IOrder
{
public decimal SubTotal
{
get
{
…
}
}
…
}
In this simplified scenario, we have a Coupon that can represent a percent off an order (25% off orders of $200 or more) or a fixed amount off an order ($25 off orders $100 or more). Notice that we can use the MinimumOrderAmt property to ensure the order is of a certain value. We can also use ExecuteMaxTimes to limit the number of people that can cash in on the coupon and we can set an ExpirationDate to limit the lengh of time the coupon is executable.
Now, suppose we want to start implementing the CalculateDiscount method for our Coupon type. One test may look something like this:
[Test]
public void CalculateDiscount_TenPercentOffOrderOfTwoHundred_ReturnsTwenty()
{
//Arrange
var coupon = new Coupon()
{
CouponCode = "TestCode",
CouponType = CouponType.PercentOffOrder,
Discount = .10m,
ExecuteMaxTimes = 100,
ExpirationDate = DateTime.Today.AddYears(1),
MinimumOrderAmt = 0
};
var order = MockRepository.GenerateStub<IOrder>();
order.Stub(x => x.SubTotal).Return(200m);
//Act
var result = coupon.CalculcateDiscount(order);
//Assert
Assert.AreEqual(20, result);
}
The object under test here is obviously the Coupon, specifically the CalculateDiscount method. The first thing I do here is to create an instance of our Coupon. That is quite a bit of code just to create an instance of our Coupon. You might argue that I have set some properties here that are unnecessary for the test (CouponCode, for example) just to make the example look worse. However, it is likely that I would have to set most of those properties.
What if instead of all of that code I could have done the following:
//Arrange
var coupon = new CouponBuilder()
.WithCouponType(CouponType.PercentOffOrder)
.WithDiscount(.10m)
.Build();
Ore even:
//Arrange
var coupon = new CouponBuilder().AsValid().WithPercentageDiscount(.10m).Build();
The Builder Pattern
The Builder Pattern is a construction pattern. It’s purpose is to abstract away the construction of (complex) objects and enable you to easily construct / build an object in a step-by-step process. And, if done just so, like above, it can yield a nice, fluent interface (notice how I simply chain methods together). So let’s get started implementing our CouponBuilder:
A Simple Builder
public class CouponBuilder
{
private readonly Coupon _coupon;
public CouponBuilder()
{
_coupon = new Coupon();
}
public Coupon Build()
{
return _coupon;
}
public CouponBuilder WithCouponCode(string couponCode)
{
_coupon.CouponCode = couponCode;
return this;
}
public CouponBuilder WithDiscount(decimal discount)
{
_coupon.Discount = discount;
return this;
}
public CouponBuilder WithExpirationDate(DateTime expirationDate)
{
_coupon.ExpirationDate = expirationDate;
return this;
}
public CouponBuilder WithDescription(string description)
{
_coupon.Description = description;
return this;
}
public CouponBuilder WithExecuteMaxTimes(int executeMaxTimes)
{
_coupon.ExecuteMaxTimes = executeMaxTimes;
return this;
}
public CouponBuilder WithMinOrderAmount(decimal minOrderAmount)
{
_coupon.MinimumOrderAmt = minOrderAmount;
return this;
}
public CouponBuilder WithCouponType(CouponType couponType)
{
_coupon.CouponType = couponType;
return this;
}
}
In it’s simplest form, it is that simple. Here is the breakdown:
- You start by creating a readonly field representing the type you want to construct
- You initialize that field in the constructor of your builder
- You create a series of methods that act on the instance stored in that field. Each method returns an instance of the Builder. This allows for that fluent interface.
More complex builder methods
I mentioned that this is the simplest form – a one-to-one relationship between builder method and property I want to set. You need not do that. You can add builder methods that logically bundle up the setting of multiple properties. Some simple examples for our example would be adding an AsValid() and WithDiscount(decimal discount). Let’s see that:
public CouponBuilder AsValid()
{
return WithExecuteMaxTimes(100)
.WithExpirationDate(DateTime.Today.AddYears(1))
.WithMinOrderAmount(0);
}
public CouponBuilder WithPercentageDiscount(decimal discount)
{
return WithCouponType(CouponType.PercentOffOrder)
.WithDiscount(discount);
}
Smart Defaults
In most of my builders, I set some smart defaults in the constructor. That is, I set the defaults to be those most commonly used in my tests. Here is the updated CouponBuilder ctor:
public CouponBuilder()
{
_coupon = new Coupon();
WithCouponCode("TestCode")
.WithCouponType(CouponType.PercentOffOrder)
.WithDiscount(.25m)
.WithDescription("Test Description")
.WithExecuteMaxTimes(100)
.WithExpirationDate(DateTime.Today.AddYears(1))
.WithId(1)
.WithMinOrderAmount(0);
}
Private Setters
Notice how my Coupon class has a private setter. It is a common and good practice to make ids immutable. However, you may want to have the ability to set your id for testing purposes. Our builder class is a perfect place for that. (*** remember that this will just be used in our tests). Have a look at my WithId builder method:
public CouponBuilder WithId(int id)
{
_coupon.GetType().GetProperty("Id").SetValue(_coupon, id, null);
return this;
}
Conclusion
The Builder Pattern is a great tool for, among other things, constructing objects for your tests. Writing them up front will save you loads of time throughout the lifetime of your project. Personally, I have a simple ReSharper template I use to create the Builder methods. Feel free to email me and I will send it to you…
Twas the Release Before Christmas
A geekier rendition of Twas the Night Before Christmas was just posted on the devEducate blog.
Entity Framework Modeling: Table Splitting
I have released a new post in the Entity Framework series at deveducate.com. The post illustrates how to take advantage of Table Splitting in Entity Framework 4.
I’m Baaaaaack
My blogging has moved to www.deveducate.com/blog
You may be wondering where I have been lately and why I haven’t been posting. Well, I have great news. I’m back blogging, but at a new location: www.deveducate.com/blog. You can subscribe to the rss feed here.
Over the past 10 months, I’ve been busy creating deveducate.com, as well as developing our first training session: “Understanding Entity Framework 4”. I also did a West Coast (USA) tour, speaking on the Entity Framework at Microsoft offices in 5 cities.
What is DevEducate.com?
DevEducate.com is my baby – so don’t call it ugly. BTW, did you ever notice that everyone thinks that their baby is cute – and yet there are ugly babies… Just sayin’.
Seriously, I have a huge passion for teaching people how to exploit technology in their applications. DevEducate.com is the company I founded to do just that. We are an online training company whose goal is to simplify learning complex technologies.
Patterns-Based Silverlight Development Blog / Screencast Series Index
I am in the midst of putting together a blog / screencast series illustrating developing Silverlight 3 application, taking advantage of various design patterns. Some of the patterns we will cover are the Repository, the Pipeline, the Service Agent and Model View ViewModel. I will be building a Sample HelpDesk Application along the way (see below).
I will keep this post updated with the links to all of the blog posts and screencasts:
Blog Posts
- Patterns-Based Silverlight Development – Part I – Getting Started
- Patterns-Based Silverlight Development – Part II – Repository and Validation
- Patterns-Based Silverlight Development – Part III – Pipeline Pattern
Screencasts
Screenshot
The following is a screenshot of the sample application we will be creating throughout this series.
Patterns-Based Silverlight Development – Part III – Pipeline Pattern
Introduction
In yesterday’s post, I build our Repository interface and the implementation, as well as added some server-side validation, following a simple pattern. I also added a test project and wrote some tests to test the our validation logic. In this post I will implement the Pipeline pattern. I will then implement a fake repository and use it to test our Pipeline.
Acknowledgements
Most of what you will see in this post follows very closely with what Rob Connery outlined in his MVC Storefront series. I am, however, not using TDD, as that is not the goal of this series. Again, I would highly recommend following his series if you haven’t already.
The Pipeline Pattern
“In software engineering, a pipeline consists of a chain of processing elements …, arranged so that the output of each element is the input of the next.” – Wikipedia – Pipeline (software)
Whether we know it or not, we have all used pipelines. Perhaps the best examples are WCF or IIS. The description above from Wikipedia (the purveyor of all knowledge) hit the most salient points on the head. You have a chain of processing elements. Each element takes an input and has an output. The output of one element is the input of another. In a typical pipeline, each element is designed to take in an input of a specific type, perform some operation on it, and return the same type as the output.
IQueryable<T> Overview
The following comes straight from the online documentation for IQueryable<T> and are quite illuminating.
The Expression property returns the expression tree that is associated with the IQueryable instance. When you do things like add a ‘where’ or a ‘select’ or ‘order by’ (the list goes on …) to your query, it is stored in the expression tree. This in-memory representation of your query is the key enabler for allowing deferred execution. What this means is that we can continually add to the query (the expression tree) up until the time we execute it. The query is not executed until we enumerate over the results.
Let’s take a look at a simple example that will help illustrate this. Looking back to our repository, we implemented only one fetch operation for tickets. It looks like this:
public IQueryable<Ticket> GetTickets() { return db.Tickets; }
You might have expected multiple fetch operations like GetTicketsBySeverityLevel or GetTicketsByPage. This is how we typically built this layer in the past. The challenge with this approach is that any time you wanted to return a different slice of data, you had to go back and add another operation to the Repository. With IQueryable<T>, we can simply call GetTickets and add to the query to suit our needs. So instead of implementing a GetTicketsBySeverityLevel in the Repository, we could do the following:
//Get the IQueryable<T> from the repository TicketRepository rep = new TicketRepository(); IQueryable<Ticket> query = rep.GetTickets(); //Add a where clause (by severity level) query = query.Where(t => t.SeverityLevelID == 1); //Fetch the data List<Ticket> tickets = query.ToList();
We are going to take advantage of this in implementing our Pipeline. The other enabling technology we are going to be taking advantage of is extension methods. I’ll cover that now…
Extension Methods Overview
Extension methods let you extend an existing type without actually deriving from it. At first glance, this raises some red flags surrounding security, but an extension method only has access to the public members of the type it is extending. This is no different than any other code that may operate on this type. So what is an extension method really? It is a pre-compile syntax that, among other things, enables LINQ and allows you to create more readable and maintainable code. Let’s take a look at an example to illustrate the readability/maintainability part. Let’s assume that I want to expose the functionality that will translate English to Jive. Obviously, this will operate on a string. The old-timey way to do this would to be to write a static method and consume it like so:
//Traditional Static Method public static string TranslateToJive(string text) { return translateToJive(text); }
//Call our traditional static string greeting = "Relax"; Console.WriteLine(StringExtensions.TranslateToJive(greeting));
We can easily implement this functionality as an Extension Method. Extension Methods are public static (they have to be both public and static) methods in a static class. What transforms a static method into an extension method is prepending the ‘this’ keyword to the first method parameter. Whatever the type of that parameter is the type we will be extending. For example, we could re-write our earlier example like this:
//Extension method, extending string public static string ToJive(this string text) { return translateToJive(text); }
//Call our extension method string greeting = "Relax"; Console.WriteLine(greeting.ToJive());
While both bits of code will output the same thing to the console: “Jes hang loose”, as you can see, the code with the extension method is simpler to read. In this simple example, you may not see a great increase in readability, but you will see it more clearly when we get into our pipeline example. Another great benefit of the extension method is that it provides intellisense support. We do not need to know about the existence of a TranslateToJive method that takes a string. We simply press ‘.’ after our string and we see:
Building our Pipeline
Now let’s tie all of the concepts brought out in this post together by implementing our pipeline. Our pipeline will be a bunch of extension methods that extend IQueryable<Ticket>. These extension methods will take in an IQueryable<Ticket> (or in this case extend it, logically the same thing) and return IQueryable<Ticket>. As we will see, we will be able to string a bunch of these extension methods together.
There will be some extension methods that don’t return IQueryable<Ticket>, perhaps just returning a single ticket. An example would be a “ByTicketId” extension method. Methods that do not return IQueryable<T> will end that pipeline.
Another name for the Pipeline pattern is ‘Pipes and Filters’. That name explains exactly what we want to do. We want to create a group of filters that can be applied to Tickets. Let’s create our Ticket filters.
- Create a TicketFilters static class in HelpDesk.Data
- Right-Click HelpDesk.Data –> Add –> Class
- Name it TicketFilters.cs (I put mine in a Filters folder)
- Mark the class public and static
- Add the following extension methods
public static class TicketFilters { public static IQueryable<Ticket> BySeverityLevelID( this IQueryable<Ticket> query, int id) { return query.Where(q => q.SeverityLevelID == id); } public static IQueryable<Ticket> ByPage( this IQueryable<Ticket> query, int pageNumber, int pageSize) { int skip = (pageNumber) * pageSize; return query.Skip(skip).Take(pageSize); } public static Ticket ByTicketID(this IQueryable<Ticket> query, int id) { return query.SingleOrDefault(q => q.TicketID == id); } }
Does the Pipeline Increase Readability?
Consider this scenario. You want to get the second page of 10 Tickets with a SeverityLevel of 1. Here is how you would do this without our extension methods:
var tickets = repository.GetTickets()
.Where(t => t.SeverityLevelID == 1)
.Skip(10)
.Take(10);
versus this with our extension methods:
var tickets = rep.GetTickets().BySeverityLevelID(1).ByPage(2, 10);
Quite a difference (in my opinion).
Testing our Pipeline
When I wrote the tests against my validation logic, I was able to simply cruft up a Ticket object and set whatever properties I needed to set (or not set). Here, however, I will need to call into my Repository. But do I really want to do that? Take the ByTicketID filter. It takes in an integer like 1. If we wrote our test calling this filter with a 1 and it failed it may be because there was no record in the database with an ID of 1. This may lead to a false negative. Our code actually worked as designed, the test failed because of what was in the database (or rather wasn’t).
Couldn’t we write some test precondition that checks to see if there is a record with ID = 1 in the database, if not, insert it? Yes, we could. But then, to be good citizens, we would probably want to add some code to remove the newly inserted record. We really don’t want to be in the business of managing our test database. We want to test our logic.
For this reason, what we might want to do is to use a fake or mock repository. Rhino Mocks is a popular framework that provides this functionality (and there are many other great tools). However, for the purpose of this post, I am going to simply implement my own fake repository. In future posts, I may replace that with Rhino Mocks or another solution.
Add The Fake Ticket Repository
- Right-click the HelpDesk.Server.Tests project –> Add –> New Folder –> Name it Fakes
- Right-click the Fakes folder –> Add –> Class
- Name it FakeTicketRepository.cs
- Mark it public
- Add the following code:
public class FakeTicketRepository : ITicketRepository { private List<Ticket> ticketList; private List<SeverityLevel> severityLevelList; public FakeTicketRepository(List<Ticket> tickets, List<SeverityLevel> severityLevels) { ticketList = tickets; severityLevelList = severityLevels; } public IQueryable<Ticket> GetTickets() { return ticketList.AsQueryable(); } public IQueryable<SeverityLevel> GetSeverityLevels() { return severityLevelList.AsQueryable(); } public void Add(Ticket ticket) { ticketList.Add(ticket); } public void Delete(Ticket ticket) { ticketList.Remove(ticket); } public void Save() { foreach (Ticket ticket in ticketList) { if (!ticket.IsValid) throw new ValidationException("Rule violations"); } return; } #region Helper Static Methods public static FakeTicketRepository CreateFakeTicketRepository() { var repository = new FakeTicketRepository(CreateTestTickets(), CreateTestSeverityLevels()); return repository; } public static List<SeverityLevel> CreateTestSeverityLevels() { List<SeverityLevel> slevels = new List<SeverityLevel>(); slevels.Add(new SeverityLevel() { SeverityLevelID = 1, Level = "High" }); slevels.Add(new SeverityLevel() { SeverityLevelID = 2, Level = "Medium" }); slevels.Add(new SeverityLevel() { SeverityLevelID = 3, Level = "Low" }); return slevels; } public static List<Ticket> CreateTestTickets() { List<Ticket> tickets = new List<Ticket>(); for (int i = 0; i < 10; i++) { Ticket sampleTicket = new Ticket() { TicketID = i, ShortDescription = "Short Description " + i.ToString(), LongDescription = "Long Description " + i.ToString(), TicketDate = DateTime.Now.AddDays(i * -1), IsOpen = (i % 2 == 0), SeverityLevelID = 1, SeverityLevel = CreateTestSeverityLevels()[0] }; tickets.Add(sampleTicket); } return tickets; } #endregion }
What you should gather from this code is the following:
- I am using generic Lists (List<T>) to store my fake ticket and severity level data
- I overloaded the constructor, forcing you to pass in the fake Ticket and SeverityLevel lists
- I implemented IRepository. All of the IRepository implementations operate on the local Lists
- I created a helper static method CreateFakeTicketRepository that will return a FakeTicketRepository with fake data in it. If you don’t feel like creating your own fake data and passing it in, you can use this out-of-the-box fake data.
Some Pipeline Tests
[TestMethod] public void Passing_ByTicketID_Filter_1_Returns_The_Appropriate_Ticket() { ITicketRepository rep = Fakes.FakeTicketRepository.CreateFakeTicketRepository(); Ticket ticket = rep.GetTickets() .ByTicketID(1); Assert.IsTrue(ticket.TicketID == 1); } [TestMethod] public void Passing_ByPage_Filter_Page_1_PageSize_3_Should_Return_Tickets_With_IDS_3_4_5() { ITicketRepository rep = Fakes.FakeTicketRepository.CreateFakeTicketRepository(); var tickets = rep.GetTickets().ByPage(1, 3).ToList(); Assert.IsTrue(tickets[0].TicketID == 3 && tickets[1].TicketID == 4 && tickets[2].TicketID == 5); }
You can see from the above code that I am using my fake ticket repository. I am then testing some of my filters. Because I know what the test data looks like, I am assured that I am testing my filter logic and not my data.
Sample Code
You can get the sample code for implementing the pipeline here. (You will need to be a registered user of the site to get the code)
What’s Next
In the next post, I will implement the WCF Service layer.
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 Repository Pattern
“A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.” – by Edward Hieatt and Rob Mee, http://martinfowler.com/eaaCatalog/repository.html
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:
public interface ITicketRepository { IQueryable<Ticket> GetTickets(); IQueryable<SeverityLevel> GetSeverityLevels(); void Add(Ticket ticket); void Delete(Ticket ticket); void Save(); }
Add the TicketRepository implementation
public class TicketRepository { HelpDeskDataContext db = new HelpDeskDataContext(); public IQueryable<Ticket> GetTickets() { return db.Tickets; } public IQueryable<SeverityLevel> GetSeverityLevels() { return db.SeverityLevels; } public void Add(Ticket ticket) { db.Tickets.InsertOnSubmit(ticket); } public void Delete(Ticket ticket) { db.Tickets.DeleteOnSubmit(ticket); } public void Save() { db.SubmitChanges(); } }
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:
public partial class SeverityLevel : …
public partial class 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:
//Definition partial void OnValidate(System.Data.Linq.ChangeAction action);
The same partial Class (Struct) or more commonly another can contain the implementation:
partial void OnValidate(ChangeAction action) { if (!IsValid) throw new ValidationException("Rule violations prevent saving"); }
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:
RuleViolation.cs
public class RuleViolation { public string ErrorMessage { get; private set; } public string PropertyName { get; private set; } public RuleViolation(string errorMessage) { ErrorMessage = errorMessage; } public RuleViolation(string errorMessage, string propertyName) { ErrorMessage = errorMessage; PropertyName = propertyName; } }
RuleViolation is a simple class with 2 primitives that allow you to indicate the ErrorMessage and optionally the name of the Property that caused the violation.
Ticket.cs
public partial class Ticket { public const string ShortDescriptionRequired = "Short Description is required"; public const string LongDescriptionRequired = "Long Description is required"; public const string ShortDescriptionTooLong = "Short Description cannot exceed 50 characters"; public const string LongDescriptionTooLong = "Long Description cannot exceed 500 characters"; public const string TicketDateRequired = "Ticket Date is required"; public const string TicketDateCannotExceedCurrentDate = "Ticket Date cannot be greater than the current date"; public bool IsValid { get { return (GetRuleViolations().Count() == 0); } } public IEnumerable<RuleViolation> GetRuleViolations() { if (String.IsNullOrEmpty(ShortDescription)) yield return new RuleViolation(ShortDescriptionRequired, "ShortDescription"); if (!String.IsNullOrEmpty(ShortDescription) && ShortDescription.Trim().Length > 50) yield return new RuleViolation(ShortDescriptionTooLong, "ShortDescription"); if (String.IsNullOrEmpty(LongDescription)) yield return new RuleViolation(LongDescriptionRequired, "LongDescription"); if (!String.IsNullOrEmpty(LongDescription) && LongDescription.Trim().Length > 500) yield return new RuleViolation(LongDescriptionTooLong, "LongDescription"); if (this.TicketDate == null) yield return new RuleViolation(TicketDateRequired, "TicketDate"); if (this.TicketDate > DateTime.Now) yield return new RuleViolation(TicketDateCannotExceedCurrentDate, "TicketDate"); yield break; } partial void OnValidate(ChangeAction action) { if (!IsValid) throw new ValidationException("Rule violations prevent saving"); } }
(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.
ValidationException.cs
public class ValidationException : Exception { public ValidationException() { } public ValidationException(string message) : base(message) { } public ValidationException(string message, Exception inner) : base(message, inner) { } protected ValidationException( SerializationInfo info, StreamingContext context) : base(info, context) { } }
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.
Add a Test Project
- Right-Click on the Server Solution Folder –> Add –> New Project
- Under Visual C# –> Choose ‘Test’ –> Choose ‘Test Project’
- Name it HelpDesk.Server.Tests
- Add a reference to HelpDesk.Data
- Delete the stubbed out test files:
- AuthoringTests.txt
- ManualTest1.mht
- UnitTest1.cs
Add a Test Class
- Right-Click on the HelpDesk.Server.Tests Project –> Add –> New Item
- Under Visual C# Items –> Choose ‘Unit Test’
- Name it TicketTests
- Delete the stubbed out code
Add a couple tests to Test our Validation logic
Now we just need to add the tests to test our logic. Take a look:
[TestClass] public class TicketTests { [TestMethod] public void Ticket_Should_Be_Invalid_When_ShortDescription_Is_Empty() { Ticket ticket = new Ticket(); ticket.TicketID = 1; ticket.LongDescription = "Test"; ticket.IsOpen = false; ticket.SeverityLevel = new SeverityLevel() { SeverityLevelID = 1, Level = "High" }; ticket.SeverityLevelID = 1; ticket.TicketDate = DateTime.Now; //Make sure ShortDescription is empty ticket.ShortDescription = ""; bool isValid = ticket.IsValid; Assert.IsFalse(isValid); } [TestMethod] public void Ticket_Should_Be_Invalid_When_ShortDescription_Is_GreaterThan_50_In_This_Case_60() { Ticket ticket = new Ticket(); ticket.TicketID = 1; ticket.LongDescription = "Test"; ticket.IsOpen = false; ticket.SeverityLevel = new SeverityLevel() { SeverityLevelID = 1, Level = "High" }; ticket.SeverityLevelID = 1; ticket.TicketDate = DateTime.Now; //Set the ShortDescription to 60 ticket.ShortDescription = "123456789012345678901234567890123456789012345678901234567890"; bool isValid = ticket.IsValid; Assert.IsFalse(isValid); } [TestMethod] public void Ticket_Should_Be_Valid_When_All_Properties_Are_Correct() { Ticket ticket = new Ticket(); ticket.TicketID = 1; ticket.ShortDescription = "Test"; ticket.LongDescription = "Test"; ticket.IsOpen = false; ticket.SeverityLevel = new SeverityLevel() { SeverityLevelID = 1, Level = "High" }; ticket.SeverityLevelID = 1; ticket.TicketDate = DateTime.Now; bool isValid = ticket.IsValid; Assert.IsTrue(isValid); } }
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).
Here is what it looks like when I run the tests:
Sample Code
You can get the sample code for Building the Repository and Validation here. (You will need to be a registered user of the site to get the code)
What’s Next
In the next post, I will implement the Filter layer. At that point I will need to go through my Repository (or my Fake / Mock repository) when testing.
Patterns-Based Silverlight Development – Part I – Getting Started
Introduction
During the summer I put together a session on Patterns-Based Silverlight Development that we delivered across the West Region as part of MSDN events. The session was structured around building a Silverlight application from the ground up that illustrated the use of the following design patterns: 1) Repository, 2) Pipeline, 3) Service Agent and 4) Model View ViewModel. The goal was not to build a final productionized version of the application, rather illustrate how one might take advantage of these patterns in a Silverlight application. I will follow the same plan here, albeit in more detail.
Environment and Demo Choices
Development Environment:
- Visual Studio 2008 sp1
- .NET Framework 3.5 sp1
- Silverlight 3
- The Silverlight 3 tools for Visual Studio 2008 sp1
- The Silverlight 3 Toolkit – July 2009 drop
* There is no reason you wouldn’t be able to follow along using our free tools
Demo Choices:
Whenever you put together a sample application, you have to make some choices: Language, Web Services Stack, REST vs. SOAP, data access strategy, etc. The following is a listing of some of the choices I made for this sample to start with (I may swap in and out as things progress):
- Language: C#
- Data Access: LINQ to SQL – This was a random decision. I had done a bunch of work with the EF lately. Thought I’d give it a go. I may swap this layer out later for the EF when .NET 4 hits Beta 2
- Web Services: WCF, SOAP, New custom Silverlight binding
Setting up the Project
I set up Visual Studio to use solution folders to clearly illustrate what is server code and what is client code. Here is what it will look like eventually:
We are going to start with creating a blank solution and add the 2 solution folders. We will then add the HelpDesk.Data project to the Server solution folder.
- Create a blank solution
- On the File menu, select New and then click Project
- Under Project types, select Other Project Types and then select Visual Studio Solutions
- Select Blank Solution
- Name it HelpDesk
- Add the ‘Client’ and ‘Server’ solution folders
- Right-Click on the Solution
- Choose Add -> New Solution Folder -> Name it ‘Client’
- Repeat for ‘Server’
- Add the HelpDesk.Data class library
- Right-Click on the Server solution folder
- Choose Add -> New Project
- Under Windows -> Choose Class Library
- Name it HelpDesk.Data
- Delete Class1
Data Model
I am using a VERY simple data model I crufted up. There is a Ticket table with a SeverityLevel Lookup table. See below:
Building the LINQ to SQL Model
I assumed that this part of the application would take under 5 minutes. As it turns out, that was a poor estimate. The issue I had surrounded serializing the generated L2S objects. It took me hours to realize that the Visual Studio designer did not support configuring the serialization in the way I needed it (at least I couldn’t figure it out). Truthfully, I could have skipped all of that pain and manually decorated the classes with the appropriate attributes up front, but I wanted to use the designer, if for no other reason than it would save me from re-decorating the classes every time I re-generated the classes. In the end, I was able to get partway there with the designer, but did have to make a change in the code, as well. Let’s walk through the process:
Adding the Tables to the Designer
- Add a LINQ to SQL named HelpDesk.dbml to the HelpDesk.Data project.
- Right-Click the HelpDesk.Data project –> Add –> New Item
- Choose Visual C# Items –> Data –> LINQ to SQL Classes
- Name it HelpDesk.dbml
- Add the ‘Ticket’ and ‘SeverityLevelLookup’ tables to the L2S designer
- From the ‘Server Explorer’, expand the Tables Node from the HelpDesk Database
- Drag the ‘Ticket’ and ‘SeverityLevelLookup’ tables onto the designer
- Make some simple adjustments to the model
- Rename the ‘SeverityLevel’ property to ‘Level’
- Rename the ‘SeverityLevelLookup’ Class to be ‘SeverityLevel’
Configure the Classes to be Serializable
By default the “Serialization Mode” for the Model is set to None:
What does that mean? Well, the default serializer for WCF is the DataContractSerializer. When it was first released (Fx 3.0), it required you to apply the DataContractAttribute to classes you wanted to serialize and to apply the the DataMemberAttribute to fields and properties you wanted to be serialized. WCF 3.5 sp1 lifted this restriction, allowing for the serialization for POCOs (Plain Old C# CLR Objects). The Serialization Mode of None simply indicates that the designer will not add any DataContractAttributes or DataMemberAttributes to your classes or properties, respectively.
Do I really need to decorate my classes? I mentioned POCO serialization support. The reality is that if you have any relationships between your classes, you will need to decorate your classes. So the first step is to set this Serialization Mode to Unidirectional. Incidentally, you can click on the properties pane and then click on any white space in the designer to view the properties for the DataContext.
This means that the classes in the model will be decorated with a DataContractAttribute and some public properties will be decorated with a DataMemberAttribute. So which properties are decorated. To start with, all, public primatives will be decorated. What we have to now understand is which complex types will be decorated. This is where the term ‘Unidirectional’ takes on importance. Essentially, if you take a look at the generated classes, the SeverityLevel class contains a collection of Tickets and the Ticket class has a SeverityLevel object. Hopefully, you can see that if we serialized both sides of the relationship, we will create an endless loop. What Unidirectional then means is that we will support serializing one side of the relationship. By default, by choosing Unidirectional, we will serialize the parent class and the child collection. So, in this case, if we serialize the SeverityLevel class, we will by default serialize it’s collection of Tickets. Have a look at the designer (I clicked on the relationship arrow in the designer):
If you take a look at the HelpDesk.designer.cs file, you can see the actual code that gets generated.
Notice below that the Tickets collection is decorated with a DataMemberAttribute in the SeverityLevel class. Also notice that the SeverityLevel property is not decorated in the Ticket class.
This default behavior does not suit the needs of my application. It does not make sense to fetch a particular SeverityLevel (like Low, Medium or High) and with it a collection of Tickets. It does, however make sense to return a SeverityLevel type when fetching a Ticket. I need to change the direction of serialization. This is the point where spent all of my time. I was not able to find the appropriate settings in the designer to accomplish this task. Clearly, I could have simply taken the 30 seconds to delete the DataMemberAttribute above the Tickets property and added one above the SeverityLevel property. However, as I stated, every time the code was regenerated, I would have to remember to make this change. (*** It is highly likely that there is a way to do accomplish this in the designer. If you know how, please leave me a comment and I will update this post ***).
I was able to get partially there in the designer. By setting the Child property to ‘Internal’, I was able to prevent the Tickets collection from being decorated:
That left decorating the SeverityLevel property in the Ticket class. I simply did that manually. Now my LINQ to SQL model is ready to go.
What’s Next
Tomorrow I will build a repository layer and illustrate the value of that pattern.





Email Me