Going Subsonic


I am in the midst of retooling one of our tools at work and I need to clean up the data access (done with .NET tiers). As I was working on how to work out thedata access, I thought about Rob Conery’s MVP ECommerce series. In this project, Rob uses the Repository pattern for data access, so let’s talk about that for a second.
 

Repository Pattern

The norm you see in many ASP.NET applications, or even Windows applications for that matter, is a straight-forward progression from UI to database. It looks something like this:

Typical Flow

The problem with this model is it is hard to test your code without actually performing data access. Now, you probably know I am not against testing your data access with a unit test framework, as long as you realize these are integration tests and not unit tests. I also advocate keeping these in different classes and ultimately different assemblies, as they serve very different purposes.

The repository pattern turns this method on its ear a bit, as you feed the Repository to your code rather than have your code call the Repository. By flipping, you can easily create a mock repository, either by creating one in your test assembly (as Rob has done in his project) or by using a Mock framework (I am currently fond of Rhino Mocks, but this could just be my flavor of the month, as I am still trying to determine what exactly I really want in a mock framework). Off the tangent about mocks, the pattern looks more like this:

Repository Flow

Now, this is actually a pretty poor diagram, as you are not necessarily feeding the Repository at the business level, but you can see a bit of the inversion from "normal" flow. This is testable as you can code more like so (from Rob Conery’s ECommerce source). Note that this is only a small portion of the test repository and test code.

 

namespace Commerce.MVC.Data {

    public class TestCatalogRepository : ICatalogRepository {

 

        public IQueryable<ProductReview> GetReviews() {

            List<ProductReview> result = new List<ProductReview>();

            for (int i = 1; i <= 30; i++) {

 

                ProductReview review = new ProductReview();

                review.Author = "TestAuthor";

                review.Body = "lorem ipsum";

                review.Email = "email@nowhere.com";

                review.ProductID = i;

                review.ID = i;

                result.Add(review);

            }

            return result.AsQueryable();

        }

 

    }

}

namespace Commerce.MVC.Tests {

        [TestMethod]

        public void Review_Repository_Can_Return_Reviews() {

 

            ICatalogRepository rep=new TestCatalogRepository();

            Assert.IsNotNull(rep.GetReviews());

 

        }

    }

}

If you need a bit deeper of a look, here is the class diagram of the pattern:

Repository UML

What this tells us is we can have some generic functions in our base class and specific functions in our derived classes, so SpecificRepository is the class we are actually running (with whatever the Repository is called).

Subsonic

One thing always leads to another and I found Rob’s other project: Subsonic. Subsonic is a code free ORM, or at least that is the main vision. There is also a tool called Substage that can generate the classes for you so you can incorporate them in your own project, as Subsonic requires full trust (something you WILL NOT get with many ISPs).

I have not gotten deep enough into Subsonic to state it is definitely my ORM on this project, but I like what I see thus far. My only issue is I am not writing a web application. This leads me to two ways to create my classes:

  1. Create the project as a web project and "steal" the generated assemblies
  2. Use Substage

The later is my choice. The problem is you have to point it to a web application anyway. Thus, I am offering the suggestion that you should be able to use any valid application configuration to feed Substage to fire off the Subsonic engine to create your classes. As it stands right now, you point to the web directory and it reads web.config, so I am kludging this a bit to make it work, but I believe it would be better if you could point at a config rather than a folder.

Update: I was wrong. While the tool is focused on web output, you do not have to kludge it at all. In fact, you need not specify the web application in the configuration to get it working. I will accept my beating now. Open-mouthed

As with MVC Membership, I will eventually look at the Source code and figure out how to make this ORM easily accessible from all types of projects, without kludging. This is not a criticism of the work Rob and others have done thus far. I am not one to shoot a gift horse. I just see a bigger box than the one originally drawn and I want to see it filled.

I will blog about the kludge at some point and detail my journey through this project if I decide this is the ORM for me. My primary focus is testability and the Subsonic project utilizes the Repository pattern, so it already has one major thing in its favor. More forthcoming.

Peace and Grace,
Greg

Advertisements

One Response to Going Subsonic

  1. Kelly says:

    Very well written………..

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: