The code base I am currently working with has a collection class that inherits from ArrayList. The purpose of this class is to offer a unique list of objects and to provide case insensitive comparisons when adding a unique item to the collection. The collection does not need to be unique, but we a way to add unique things to the list is required.

My task the last week was to become familiar with the code base and identify possible refactorings. Using NDepend, I was able to determine that this class is typically used with strings. One possible refactoring I suggested was to replace this custom class with List<string>(). An out of sprint hit squad was formed to tackle doing just that. We came in on Saturday morning bright and early and got started.

Doing a global search and replace to change this custom ArrayList class with List<string> turned up thousands of compiler warnings where the method AddUnique() was called.

Our first stab at tackling this problem was to create a helper method that added an item to a given list only if that list did not already contain the item. We wrote a macro to quickly turn the old references into the new helper references. The code looked something like this:

tableList.AddUnique("item_table")

ListHelper.AddUnique(tableList, "item_table")

This seemed to get us around the uniqueness hurdle. It was a bit verbose, but it got the job done and would eventually allow us to get rid of the custom collection class altogether. We started hacking away, taking turns at the keyboard with three sets of eyes making sure we were hitting the right items and evaluating between List<string> and ArrayList where appropriate.

After a few hours of locating problem areas and fixing them with a handy macro we created out of sheer boredom, the hit squad decided this was not working. I mentioned that if we were using Visual Studio 2008, we could write an extension method that would simply attach an AddUnique() method to the List<string> class. We knew that Visual Studio 2008 allowed you to target the 2.0 framework. So we could upgrade the solution to VS2k8, leave all our projects targeting 2.0 and be able to use extension methods.

I left the 8 hour marathon triple-programming session with the goal of playing around with implementing extension methods in Visual Studio 2008. Since I was not familiar with actually writing them, I fired up my IDE and wrote a couple tests for what I wanted to happen.

        [Test]
        public void Can_Add_Unique_String_To_List_Of_String()
        {
            var list = new List<String>();

            list.AddUnique("one");
            list.AddUnique("one");

            Assert.AreEqual(1, list.Count);
        }

        [Test]
        public void Can_Add_Case_Insensitive_Unique_String_To_List_Of_String()
        {
            var list = new List<string>();

            list.AddUnique("one");
            list.AddUnique("ONE");

            Assert.AreEqual(1, list.Count);
        }

I flipped over to my Extensions library and added a ListOfStringExtensions class. To get the code to compile I quickly stubbed out the method like this:

public static void AddUnique(this List<String> list, string item)  {   }

Using the ReSharper unit test runner, I verified that my test indeed fail. The moved on to implementing the method logic. My first attempt at implementing the method looked something like this:

public static void AddUnique(this List<string> list, string item)
        {
            foreach(var s in list)
            {
                if(s == item)
                    return;
            }

            list.Add(item);
        }

This allowed my first test to pass, but not the second. So I modified the implementation like so:

public static void AddUnique(this List<string> list, string item)
        {
            foreach(var s in list)
            {
                if(String.Compare(s,item,true) > 0)
                    return;
            }

            list.Add(item);
        }

Now both tests pass. I continued down this TDD path until I had a nice set of extension methods and unit tests that satisfied all the requirements to get rid of our custom collection class. In the end I created AddUnique, AddUniqueRange, CaseInsensitiveContains, IsUnique and ToUniqueList extension methods which all work nicely together with a full suit of unit tests.

The next task at hand was to get the extension methods working in projects that were targeting the 2.0 framework. I set my unit test class to target 2.0 and verified that they still worked. I got an warning as soon as I set the framework target that I had references to projects targeting a different framework. The tests ran fine.

I then changed the target of my extension library to 2.0 and got this nasty error at compile time:

Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?

Hrm.. ExtensionAttribute seems to be a 3.x feature. But I had started out this adventure reading ScottGu's blog where he says that extension methods are language syntactical sugar and should work fine with the 2.0 framework. So I fired up Chrome and hit google.

The first result for my query happened to be my good friend Nate Kohari's blog. Nate is the creator of Ninject the amazing Dependency Injection framework. He also recently release his new web site IdeaVine. He is an awesome guy  and as usual he already blazed the path I was walking down.

According to Nate, all I needed to do was add an attribute class in a specific namespace to get around the compiler issue.

 
//override the .net 3.5 compiler services for .net 2.0 compatibility
//see: http://kohari.org/2008/04/04/extension-methods-in-net-20/
namespace System.Runtime.CompilerServices  
 {  
   [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]  
   public class ExtensionAttribute : Attribute  
   {  
   }  
 } 

Everything compiles and test run fine targeting the 2.0 framework. In morning I plan to verify this by running sample code on a fresh box with only the 2.0 framework installed. As always you can get my full source code here.


 
Categories: Development | Unit Testing

At the end of yesterdays internal study group meeting, the organizer mentioned that I would be giving a presentation on NHibernate the following week. I plan to give a simple dog and pony show of persisting a simple object to the database and all of the setup needed to accomplish the task.

One of the participants asked for a brief description of NHibernate. I explained that it is an ORM framework (Object Relational Mapping). I expanded a bit by saying that NHibernate removes the dependency between your domain objects and your relational database by handling mapping from one to the other.

After a couple more questions it was determined that NHibernate generates SQL and is therefore inferior to stored procedures. It was the general feeling that stored procedures were the be all end all for performance and optimization. I attempted to explain that NHibernate generates parameterized queries which have all the advantages of cached query plans that stored procedures do. By this time the meeting was breaking up and I had a mission.

I wanted to challenge the dogmatic urban legend passed down from .NET developer to .NET developer since the classic ASP days. That dogma simply states you should always access your database via stored procedure for "performance reasons". Inline SQL is BAAAAAAD.

So I fired up Visual Studio, created a class and started writing tests.

The first thing I wanted to do was to create a baseline. I created a User table in a fresh SQLExpress database and wrote a test to pop 1000 rows into it in the crustiest "I just read my first Wrox book" way I could think of. I added some timing code and let it rip. The test looks like this:

 

       [Test]
        public void Time_Inline_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText =
                            "INSERT INTO dbo.Users "
                            + "(Handle, FirstName, LastName, Password, EmailAddress, LastLogon) "
                            + "VALUES ("
                            + "'UserHandle" + i + "',"
                            + "'UserFirstName" + i + "',"
                            + "'UserLastName" + i + "',"
                            + "'UserPassword" + i + "',"
                            + "'User" + i + "@email.com',"
                            + DateTime.Now.ToShortDateString() + ")";

                        co.ExecuteNonQuery();
                    }
                }
                c.Close();
            }
            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by inline query", 
                time.TotalMilliseconds, INSERT_COUNT));
        }

From a fresh load of my test assembly into MbUnit, this code takes 1312.5 milliseconds to run 1000 inserts. Running the test repeatedly drops the time to 437.5 miliseconds. It appears that SQL Server does some optimizations for inline inserts regardless of what the tribe tells me.

Next up, I wanted to see if parameterizing the query would improve the performance. The test case looks like this:

        [Test]
        public void Time_Parameterized_Query_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText =
                            "INSERT INTO dbo.Users (Handle, FirstName, LastName, Password, EmailAddress, LastLogon) VALUES (@p1,@p2,@p3,@p4,@p5,@p6)";
                        co.CommandType = System.Data.CommandType.Text;
                        co.Parameters.AddWithValue("@p1", "UserHandle" + i);
                        co.Parameters.AddWithValue("@p2", "UserFirstName" + i);
                        co.Parameters.AddWithValue("@p3", "UserLastName" + i);
                        co.Parameters.AddWithValue("@p4", "UserPassword" + i);
                        co.Parameters.AddWithValue("@p5", "User" + i + "@email.com");
                        SqlParameter param = new SqlParameter("@p6", SqlDbType.DateTime);
                        param.Value = new DateTime(2000, 1, 1);
                        co.Parameters.Add(param);

                        co.ExecuteNonQuery();

                    }
                }
                c.Close();
            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by parameterized query", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1296.9 milliseconds on a fresh load of my test assembly. Repeated runs drops the test run to ~350 milliseconds a slight advantage over the inline query. I imagine this gap would widen with a more complex query.

Finally, we have the acclaimed SQL Stored Procedure dogmatic method of how everything should be done! The stored procedure in the code below is pretty much exactly what you expect it to be.

       [Test]
        public void Time_Stored_Proceedure_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText = "AddUser";
                        co.CommandType = CommandType.StoredProcedure;
                        co.Parameters.AddWithValue("@p1", "UserHandle" + i);
                        co.Parameters.AddWithValue("@p2", "UserFirstName" + i);
                        co.Parameters.AddWithValue("@p3", "UserLastName" + i);
                        co.Parameters.AddWithValue("@p4", "UserPassword" + i);
                        co.Parameters.AddWithValue("@p5", "User" + i + "@email.com");
                        SqlParameter param = new SqlParameter("@p6", SqlDbType.DateTime);
                        param.Value = new DateTime(2000, 1, 1);
                        co.Parameters.Add(param);

                        co.ExecuteNonQuery();

                    }
                }
                c.Close();
            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by stored proceedure", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs unexpectedly in 1390.6ms. This seems like quite a long time for a stored procedure that is stored in the database and from my understanding with a query plan in place. Subsequent executions of the test yield execution times ~320ms. Just to verify this, I closed the MbUnit test runner application and reran these tests. I got the same results.

Now that we have a baseline of the various direct SQL methods that are well accepted in the .NET community, I want to see how NHibernate performs at these tasks. I see two methods available though NHibernate spinning up a session and cramming User objects into its Save() method and adding a transaction into the mix.

My first NHibernate test looks like this:

       [Test]
        public void Time_NHibernate_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;
            using (ISession session = factory.OpenSession())
            {
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    User u = new User();
                    u.Handle = "UserHandle" + i;
                    u.FirstName = "UserFirstName" + i;
                    u.LastName = "UserLastName" + i;
                    u.Password = "UserPassword" + i;
                    u.EmailAddress = "User" + i + "@email.com";
                    u.LastLogon = DateTime.Now;

                    session.Save(u);

                }
                session.Close();

            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by nhibernate", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1656.3ms with reruns clocking in at ~560ms. It looks like NHibernate might have a slight performance hit when compared to stored procedures.

My last test using NHibernate transactions looks like this:

       [Test]
        public void Time_NHibernate_Tansaction_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;
            using (ISession session = factory.OpenSession())
            {

                ITransaction transaction = session.BeginTransaction();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    User u = new User();
                    u.Handle = "UserHandle" + i;
                    u.FirstName = "UserFirstName" + i;
                    u.LastName = "UserLastName" + i;
                    u.Password = "UserPassword" + i;
                    u.EmailAddress = "User" + i + "@email.com";
                    u.LastLogon = DateTime.Now;

                    session.Save(u);

                }
                transaction.Commit();
                session.Close();

            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by nhibernate with transaction", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1406.3ms with follow up runs in 300ms. A dramatic increase in performance over over the non transactional processing. So the final performance test results looks something like this:

Test 1st Run nth Run
Inline SQL 1312.5ms ~430ms
Parameterized Query 1296.9ms ~350ms
Stored Procedure 1390.6ms ~320ms
NHibernate 1565.3ms ~560ms
NHibernate w/Transaction 1406.3ms ~300ms

I am not going to try to interpret these results, but simply publish them and see what feedback I get from the collective. My next steps are to increase the complexity of what I am doing; add some joins into the mix. I want to see if the performance gap widens or a clear winner emerges.

If you would like to see the entire code base for these tests, I have published them to my CodePlex repository and would love to hear your ideas on squeezing out performance with both SQL and NHibernate. Look for the NHibTester solution.


 
Categories: Performace | Tools | Unit Testing

In a recent post, I discovered a flaw in my world domination plot. I had written a Unit Test to test my expectation that the method GetByID() of the class UserRepository returned the expected User. When UserRepository.GetById() is called, it calls IDataProvider.GetById(), which returns an instance User to the UserRepository which in turn returns it to the caller.

My UserRepository class delegates database access to the interface IDataProvider. This allows me to substitute any implementation of IDataProvider to satisfy this responsibility. In non testing code I use Dependancy Injection to map UserDataProvier to IDataProvider. But in testing code I do not really want to hit a database as it slows the testing process down. So I use Rhino.Mocks instead.

Rhino.Mocks is a framework for creating mock objects for use in Unit Testing. Provide Rhino.Mocks with an Interface and it will give you back an object that implements that interface. You can also tell it to expect certain calls against the interface and how it should respond.

My Unit Test looked something like this:

      [Test]
        public void GetByIdTest()
        {
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetById(1)).Return(new User() { Id = 1 });

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

As you can see this test, creates a MockRepository that is provided by the Rhino.Mocks framework. It then declares an instance of IDataProvider but delegates the creation of that instance to the MockRepository's CreateMock method. This tells Rhino.Mocks to create a dummy instance of the IDataProvider interface. Next we new up a UserRepository (the actual target of the unit test) and provide our mocked IDataProvider to it's constructor. Then we tell Rhino.Mocks to expect a call to our mock IDataProvider's GetById method and to return a new instance of User with it's Id property set to 1. Finally, we do our testing and validation.

This test fails to compile. The entity class User has read only properties. Id happens to be one of them. In the domain model for this particular application Id is a unique identifier and once a User instance is returned from the data access layer, it should never be modified.

So this presents a unique challenge, how do I test that UserRepository.GetById(1) returns an instance of User with an Id of 1?

I went down the path of trying to use Ninject (an Inversion of Control container), to inject the value in a newed up instance. But this had code smell for me. Why am I creating a dependency on Ninject to get my Unit Tests to work. That just seemed wrong to me. So I began digging in the Rhino.Mocks documentation wiki to see if it had a method for resolving this.

That was when Aiden Montgomery in the #ALT.NET IRC channel suggested that I use Reflection. He even went so far as to download my source from CodePlex and demonstrate what he was suggesting in my application.

The final test ended up looking something like this:

[Test]
        public void GetByIdTest()
        {
            MockRepository mock = new MockRepository();
            
            Type userType = typeof(User);
            PropertyInfo pi = userType.GetProperty("Id");
            User user = new User();
            pi.SetValue(user, 1, null);

            IDataProvider dataProvider = 
                (IDataProvider) mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetById(1)).Return(user);

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

 

This of course passed, didn't add a non-BCL dependency and maintained the original intent of the test and the domain model. With all the shiny new toys, I was forgetting to see the forest through the trees and return to the simplest solution. Thanks to Aiden for bringing me back down from the clouds.


 
Categories: Development | Tools | Unit Testing

I have been reading a ton of the ALT.NET bloggers and mailing list lately. They are constantly talking about the methodology of software development and the tools they use. On the concept front Domain Driven Design, Inversion of Control, Separation of Concerns and Test Driven Development are all popular topics that have been stewing in my mind. I also wanted to give some of the tools like Nhibernate, Rhino.Mocks and Ninject a try. I was also itching to get into the new Microsoft ASP.NET MVC code.

For the last couple months, I have been festering in the swamp of legacy VB.NET spaghetti code and haven't had the time or motivation to write something fresh just for the sheer joy of creation. Friday, I kind of snapped, fired up Visual Studio 2008, downloaded the tool stack and started hacking away.

Things seemed to just click on all of the topics I had been reading about. I started out with NHibernate and getting a simple User entity to persist to a SQL Sever 2005 database. I then moved on to implementing the Repository Pattern for my User entity abstracting away the actual persistence to a DataProvider class wrapping NHibernate. By this time I had Factory Patterns all over the place, so I added a reference to Ninject.Core and got rid of those too. I then whipped out a MVC site to consume my new repository.

After an evening of furious experimentation, I had a complete database to web page end to end implementation of my User entity. I was stoked, still am. I am currently working on getting unit tests in place using Rhino.Mocks, integration tests on my data access layer and fully implementing CRUD in the MVC site. It is a hell of a lot of fun.

If anyone is interested in seeing what I am working on or want a simple example of using all these things together in an easily understandable way, I posted my work to CodePlex. If you are new to this stuff like I am, download it and check it out. If you are an old hat and want to give me some pointers or tips, please download it and fill me in.

If you work with me and happen to read my blog and are interested, I would love to talk to you about the project and what I learned and discovered. Hit me up.


 
Categories: Development | Fundamentals | Tools | Unit Testing

I came across an interesting issue tonight exploring the use of Rhino.Mocks in unit tests. I have a class UserRepository that implements my current understanding of the Repository Pattern. My repository uses the interface IDataProvider to persist my User entity. The concrete class UserDataProvider wraps NHibernate.

My goal was to write unit tests that cover the methods of UserRepository. I used Rhino.Mocks to mock away UserDataProvider to prevent actually needing a database.

Things were going fine:

public void SaveTest(){
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = 
                  (IDataProvider) mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);
            User u = new User();
            
            Expect.Call(dataProvider.Save(u)).Return(1);
            Expect.Call(dataProvider.GetById(1)).Return(u);
            
            mock.ReplayAll();
            User x = target.Save(u);
            mock.VerifyAll();

            Assert.AreEqual(x, u);
        }
 
public void GetListTest(){
            MockRepository mock = new MockRepository();
            IDataProvider dataProvider = 
                 (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetList()).Return(
                new List<object> { new User(), new User()});

            mock.ReplayAll();
            IList<User> users = target.GetList();
            mock.VerifyAll();
            Assert.AreEqual(2, users.Count);  
        }

Then I hit a snag. My User entity has a property Id that is read only. The users Id comes form the database and should not be able to be modified. So my next test has a bit of a problem and fails to compile.

public void GetByIdTest() {
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            //TODO: Interesting Problem here. My actual dataProvider uses NHib
            //and would be able to meet this expectation. But my mock
            //cannot set the read only id property so this test will not
            //even compile.
            Expect.Call(dataProvider.GetById(1)).Return(new User() { Id = 1 });

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

 

NHibernate has no problem injecting the value when I fetch the object from it, but my simple little expectation above chokes on it. I am not sure how to get around this one with out violating the intent of the test. I'll have to dig into the Rhino.Mocks documentation and see what tools it offers to get around this situation.

So far Rhino.Mocks is a great time saver. If I actually had to generate a fake for IDataProvider it would take quite a bit of time. I'll have to work it into my regular work life and see how it fairs there.

I'll update this post when I find a resolution to the issue at hand.


 
Categories: Development | Tools | Unit Testing