OOP DDD TDD LOB ORM HELL


So I'm one of those coders that is constantly trying to "refactor" my way of coding, if that makes sense... I have a natural assumption that i am not coding in the most ideal manner and the more blogs i read, the more I come to realize that I am not alone. A lot of coders out there are looking for a better way. The reason that we feel something is missing is because something is missing. The field of computer programming is in its infancy and I am excited to see what will be available in 20...50...100 years.

Fridays at my company involve me reading about coding instead of actually coding. I don't see this as a waste of time because I feel that in the long run I actually SAVE myself time. Take for example, the day I learned about O/R mappers. The 1st version of our company's bread and butter product worked with MS ACCESS as well as SQL Server. Being a brainwashed "recordsets are god" programmer (this was back in VB6 days) naturally we used stored procs and queries as access calls them. Schema changes were a nightmare and never occurred.

The application, although successful, had to evolve into where it is today. The fact that it was successful argues another point that being, the primary focus should be solving a business problem. Code "prettiness" is secondary. Nevertheless, as all applications must do in order to survive, we evolved. The next release of our version would be a complete rewrite (ut oh some might be saying) and yes I do know the cardinal rule of never doing complete rewrites, but .NET was just coming into mainstream and I felt it was time to abandon ship.

As we began the rewrite, I did not want to have stored procs ever again. I came upon NHibernate by accident. Time for yet another tangent.... For a long time in my development "career" I felt something was missing. The first time this happened was when I started reading all these Object Oriented Programming (OOP) books. They would talk about this domain model and how glorious it was, but the examples were always trivial. I'm not naive, 99% of line of business (LOB) applications involve an actual database (GASP!). I could not for the life of me figure out how we would bridge this gap and at the time, I had no clue that the whole impedance mismatch was such a real issue. (My google skills weren't up to snuff I suppose plus I was only 19 years old). Anyways... time goes by and I read more and more MSDN articles (woops!) who preach recordsets with OOP nowhere to be seen. It did not make sense to have this "Customer" class that would just have methods such as "GetAll" and "GetByLastName"... I thought a Customer would have attributes such as FirstName LastName etc... where was the OOP

NHibernate was my first eye opening moment... all of the sudden, I could code with real objects and have them persisted transparently. The next version of our application used NHibernate exclusively (although reporting bypassed it for the most part) and worked very, very well. There are parts of the application that aren't as OOP as I want, but the customers are completely satisfied so I would call it a success.

Well here we are for round 3. The application has to move from the realm of the desktop to the web. There are enough new requirements to justify at least a major rewrite (if not complete rewrite). In the time between finishing/maintaining version 2 and now, I have become a huge proponent of test driven development (TDD) and the "simplest solution possible". I am also learning more and more about domain driven design, etc. but it seems the more I learn, the more I feel I am doing wrong.

I think a lot of developers feel like there is some mystical object heaven when you finally realize all the mistakes you've been making and your applications will all of the sudden become object oriented. I can't speak for anyone else, but I'm stating that I do not feel this place exists. There are fundamental problems that all application have to solve that aren't as simple as just applying this pattern or that. Your code will get dirty, it will have pieces that touch the database directly (e.g. reporting and bulk updates/deletes) there are going to be times when you have to touch the ADO.NET namespace, when you have to work with DataSets (ICK!). This is inevitable.

As much as the object bigots would love it, you can't bottle everything up into an object. The mismatch still exists. Today is Friday and I'm having a cocktail while I write this entry. I've been thinking a LOT about my current development cycle and I am trying to refactor it! I think any developer worth a damn has to constantly strive for improvement. I am one of those developers that (unfortunately) always thinks about the big picture. This can be a good thing and a bad thing.

The good part is that you see the big picture and are able to make smart decisions about architecture (usually). The bad part is feature creep. You "know" that you are going to need some feature. Instead of focusing on the task at hand (the current use case) you constantly have big visions of the overall "architecture". Words like "framework" start popping into your head, you think about how you can abstract the current issue to solve so many other problems... you start having visions of "God" frameworks where everything can be abstracted to a Message class, I mean afterall, isn't everything in computer programming just a Message with a Response... wait... Response is really just a Message so we can do away with Response class and just have Messages and targets. This is starting to sound a lot like Smalltalk.

I guess what I'm getting at is that THERE IS NO SILVER BULLET. Your clients don't care about your architecture outside of what business problem it solves. If you are using datasets, objects, xml, json, csv, or a custom protocol (because you know you can get better performance) they don't care. What they see are a bunch of text fields on the screen that say First Name, Last Name, Address, Phone Number, and Salary. They fill them in and click Submit. They expect to be returned to a list of all the people in their database with one new entry. Whether you are using ADO.NET to save that record, NHibernate, or ODBC because ADO.NET is yet another useless layer to slow things down... they DON'T CARE. If the backend is PHP, ASP.NET, RAILS, or CGI - they also don't care. What they do care about is features and turnaround time on new features.

And this is where OOP and all these other ideas can help. Because sure, in a finite world, the application should be implemented in the fastest way possible. But how many applications are stagnant entities... almost 0. The users will want new features... how are you going to implement those? Well let's see what the major requirements are for a simple change... say we now need to store a Social Security Number field on clients. This is the sort of change we see in our application all the time and we've got a pretty good way of dealing with it. This being a Windows application with an SQL Server backend, here is how we cope with change.

Problem: Field needs added

1. Column needs to be added to schema

2. Property needs to be added to object (if you use classes like we do) e.g. Customer.SocialSecurityNumber

3. User interface element needs added on at least one screen to modify SSN (most likely more to display in grids etc.)

How do we handle it currently?

1. We have a schema script embedded in our app where we add the SQL to add the column (scripts are run at startup to update schema)

2. Add property to class

3. Add property element to NHibernate mapping

3. Add textbox to windows forms (and columns to listviews etc.)

4. Code to link to backend object for saving

I am able to do this in roughly 5-10 minutes for a single field being added, which isn't that bad. The next version we hope to be able to do this IMMEDIATELY. Single change to class by adding a property and perhaps some GUI code. Anyways - I've gone on a tangent and I've gotta roll. Peace out people.

author: Patrick | posted @ Friday, December 05, 2008 8:19 PM | Feedback (0)

Test Driven Javascript Part 2


So I got a good night's sleep and had a nice workout this morning and came up with a some great refactorings for TDD with Javascript.

I have simplified the code base tremendously and added to the expressiveness.

The basic idea for my TDD/JS framework is that you still use NUnit/TestDriven.Net. Yesterday's version used tests that were implemented in javascript files, after thinking about it, I've decided to implement the tests in actual C# files as you will see in a few seconds.

First let's go over the problem... TDD with Javascript is HARD and a pain in the ass. I don't want to work in the browser to do my TDD because that means I have to leave the environment I love so much (VS2008 IDE). I don't want to reinvent the wheel either... and I love TestDriven.Net's ease of testing...

So the current solution goes as follows:

1. We have an abstract base class called JavascriptTest which your test classes will inherit from.

2. Your test classes will continue to work very similarly to how they do in the C# world

Let's dig into the code

First I will show you the test class that I have been using while I developed the framework - it's ridiculously simple and probably doesn't make any sense...

 

    [TestFixture]
    public class TimeTest : JavascriptTest
    {
        protected override void AddScripts(ScriptManager scripts)
        {
            scripts.AddScriptFile(@"C:\Projects\Web\js\Time.js");       
        }

        [Test]
        public void TodayReturnsToday()
        {
            Test(
                "var t = new Time();" +
                "assert.areEqual('today', t.today());"
            );
        }

        [Test]
        public void TomorrowReturnsTomorrow()
        {
            Test(
                "var t = new Time();" +
                "assert.areEqual('tomorrow', t.tomorrow());"
            );
        }
    }
 

You see the normal NUnit attributes applied and that we inherit from the JavascriptTest class. There is a mandatory method that we override called AddScripts which is used to tell the framework where the javascripts that we want to test are located. Currently, I am pointing that to a javascript file in a web project in the same solution.

The test methods have the same Test attribute you would normally apply, but they use the Test function on the JavascriptTest base to run the test. This was a design decision that I'm not 100% sure on yet, but I think the benefits of the actual tests being run in NUnit outweights having to concat strings to build your test scripts. Let's take a look at the JavascriptTest class now.

 

    [TestFixture]
    public abstract class JavascriptTest
    {
        private ScriptManager scripts;
        private JavascriptHost host;

        protected abstract void AddScripts(ScriptManager scripts);

        [TestFixtureSetUp()]
        public void TestFixtureSetUp()
        {
            scripts = new ScriptManager();
            AddScripts(scripts);
            host = new JavascriptHost(scripts);
        }

        protected void Test(string javascriptTest)
        {
            host.RunTest(javascriptTest);   
        }

        [TestFixtureTearDown()]
        public void TestFixtureTearDown()
        {
            host.Dispose();
        }
    }

 

This class is very simple and delegates most of its work to the JavascriptHost class. We have an instance of a ScriptManager class and a JavascriptHost class. We have a TestFixtureSetUp method where we initialize our host and our script manager and load the scripts from our derived classes. In the tear down we cleanup. The Test method which the clients call with the javascript test is passed on to the host.

Let's take a look at the ScriptManager class.

 

    public class ScriptManager
    {
        private IList scripts;

        public ScriptManager()
        {
            this.scripts = new List();
        }

        public void AddScriptText(string script)
        {
            this.scripts.Add(script);
        }

        public void AddScriptFolder(string jsFolder)
        {
            foreach (FileInfo file in new DirectoryInfo(jsFolder).GetFiles("*.js"))
            {
                AddScriptFile(file.FullName);
            }
        }

        public void AddScriptFile(string jsFile)
        {
            AddScriptText(File.ReadAllText(jsFile));
        }

        public string ToJavascript()
        {
            return this.scripts.Aggregate((all, curr) => all + "\r\n" + curr);
        }
    }

This class has only one purpose, to collect the scripts that the client wants to test. It has convenience methods to load scripts or an entire folder. This class will grow to add recursive directory searching etc, but for now it's fairly simple. It has one method ToJavascript() which concatenates all the scripts into a single script. NOTE: This class does not store file references, it stores the actual scripts located in the files. Our host class will be injecting javascript not links to the javascript files.

The majority of the work is done in our JavascriptHost class so let's look at that.

 

    [ComVisible(true)]
    public class JavascriptHost : Form
    {
        private WebBrowser webBrowser;
        private ScriptManager scripts;

        public JavascriptAssert Assert { get; private set; }
        
        public JavascriptHost(ScriptManager scripts)
        {
            this.webBrowser = new WebBrowser();
            this.webBrowser.ObjectForScripting = this;
            this.webBrowser.ScriptErrorsSuppressed = true;
            this.scripts = scripts;
            this.Assert = new JavascriptAssert();
            this.Controls.Add(this.webBrowser);
        }

        public void RunTest(string javascriptTest)
        {
            BuildWebPage();
            InjectScript(javascriptTest);
            InvokeScript();
        }

        private void InvokeScript()
        {
            webBrowser.Document.InvokeScript("test");
            Assert.CheckAssertions();
        }

        private void InjectScript(string javascriptTest)
        {
            HtmlElement body = webBrowser.Document.GetElementsByTagName("body")[0];
            HtmlElement scriptElement = webBrowser.Document.CreateElement("script");
            IHTMLScriptElement element = (IHTMLScriptElement)scriptElement.DomElement;
            StringBuilder script = new StringBuilder();
            script.AppendLine("function test() {");
            script.Append(javascriptTest);
            script.Append("}");
            element.text = script.ToString();
            body.AppendChild(scriptElement);
            Assert.CheckAssertions();
        }

        private void BuildWebPage()
        {
            this.webBrowser.DocumentText = GetPageHtml();
            while (this.webBrowser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            Assert.CheckAssertions();
        }

        private string GetPageHtml()
        {
            StringBuilder html = new StringBuilder();
            StringBuilder html = new StringBuilder();
            html.AppendLine("< html>");
            html.AppendLine("< head>");

            html.AppendLine("< script type=\"text/javascript\">");
            html.AppendLine("assert = window.external.assert;");
            html.AppendLine("window.onerror = function(msg) { assert.fail(msg); }");
            html.AppendLine("< /script");

            html.AppendLine("< body>");
            html.AppendLine("< /body>");
            html.AppendLine("< script type=\"text/javascript\">");
            html.Append(scripts.ToJavascript());
            html.AppendLine("< /script>");            
            html.AppendLine("");

            return html.ToString();
            return html.ToString();
        }
    }

NOTE: tags have been modified in the HTML so that they show up in this blog by adding a space between the < and the tag name

As you can see, this class is a bit longer than the rest. First things first, this class inherits from Windows Form - this is necessary to host our WebBrowser control which will do all the work for us. At construction, the class creates a new WebBrowser control and adds it to its child controls. It disables Script errors so that we don't get popups and sets the ObjectForScripting property to itself. This property will be our window.external reference in our javascripts. Basically, it will allow our scripts to call back to the host. We have added a ComVisible attribute to the host to allow this access.

You will also see that we create a JavascriptAssert class - we'll get to this in a minute.

The RunTest method is our only public method and is invoked by the JavascriptTest class. The method basically does the following things:

1. Build a HTML document that will form the page that our WebBrowser will load (using the DocumentText property).

2. Inject our test script at the end of the web page.

3. Call our test script.

In the BuildWebPage you will see that we construct our page. The HTML generated starts with a script at the top of the page. The first line sets a local variable assert to the window.external.assert property. This is so our scripts can references assert.areEqual etc. and will actually be calling into our host's JavascriptAssert class via the Assert property on the JavascriptHost. Remember, our JavascriptHost is the window.external reference

Next thing is the window.onerror = function... script. This is used so that any subsequent scripts which cause errors (either parser errors or scripting errors) will go through our assert.fail and call back into our managed code.

The only other thing added is the scripts being tested after the body.

Next thing we do is inject our test script (the script that actually exercises our javascript) at the very end of the document. We do this by dynamically creating a script element, setting its text property to the script passed by our client (wrapped in a function called "test") and we add this element to our page.

Finally, we call our "test" function by using the InvokeScript method on the HtmlDocument.

You probably have noticed the Assert.CheckAssertions littered all over, so it's time to go over how we actually integrate with the NUnit framework... let's take a look at the JavascriptAssert class.

 

    [ComVisible(true)]
    public class JavascriptAssert
    {
        private Exception current;

        private void Try(Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                current = ex;
            }
        }

        public void AreEqual(object expected, object actual)
        {
            Try(() => Assert.AreEqual(expected, actual));
        }

        public void Fail(string message)
        {
            Try(() => Assert.Fail(message));
        }

        public void CheckAssertions()
        {
            if (current != null) throw current;
        }
    }

 

Once again you see the ComVisible attribute, this makes the class visible to our Javascript which is important because of the Assert property on the JavascriptHost. When a javascript calls assert.AreEqual(...) it is actually calling window.external.assert.areEqual. window.external references our javascript host which then resolves the Assert property to our JavascriptAssert class.

The methods on the JavascriptAssert class are basically going do coincide with NUnit's method (although we've only done 2 so far). You will notice we  wrap our NUnit Assert calls in the Try method which actually captures any exception they might throw and stores it in a current variable. The CheckAssertions method simply throws the exception if there is one.

The reason we do it this way is due to threading... Our JavascriptHost is running in the same thread as NUnit so calls to Assert.Fail etc. work as expected if they are called directly from that thread, however, our webbrowser is running javascript in a separate thread and calls back into our assert call nunit, but does not register with the testing framework correctly. This is why we have the CheckAssertions after any point where an exception could have been raised. It causes the exception to be rethrown on the correct thread and have Nunit function properly.

To show you how cool this is, I'm going to show you the output after using TestDriven.Net on the test file (above) in the following scenarios:

1. Test file does not yet exist

2. Test file exists, but Time class has not been created yet

3. Time class has been created, but the method has not yet been implemented

4. Method implemented but returns wrong value

5. Correct implementation

 

1. No Test File

TestCase 'Evo.Contact.Tests.Web.TimeTest.TodayReturnsToday' failed: TestFixtureSetUp failed in TimeTest
TestCase 'Evo.Contact.Tests.Web.TimeTest.TomorrowReturnsTomorrow' failed: TestFixtureSetUp failed in TimeTest
TestFixture failed: System.IO.FileNotFoundException : Could not find file 'C:\Evo\Projects\Contact\src\Web\js\Time.js'.

2. Blank Test File

TestCase 'Evo.Contact.Tests.Web.TimeTest.TodayReturnsToday' failed: 'Time' is undefined
TestCase 'Evo.Contact.Tests.Web.TimeTest.TomorrowReturnsTomorrow' failed: 'Time' is undefined

3. Time.js below

Time = function() {

};

Output

TestCase 'Evo.Contact.Tests.Web.TimeTest.TodayReturnsToday' failed: Object doesn't support this property or method
TestCase 'Evo.Contact.Tests.Web.TimeTest.TomorrowReturnsTomorrow' failed: Object doesn't support this property or method

4. Method Implemented with incorrect return value

Time = function() {

};

Time.prototype.today = function() { return "" };
Time.prototype.tomorrow = function() { return "" };

Output

TestCase 'Evo.Contact.Tests.Web.TimeTest.TodayReturnsToday'
failed: 
  Expected string length 5 but was 0. Strings differ at index 0.
  Expected: "today"
  But was:  

TestCase 'Evo.Contact.Tests.Web.TimeTest.TomorrowReturnsTomorrow'
failed: 
  Expected string length 5 but was 0. Strings differ at index 0.
  Expected: "today"
  But was:  

And finally, the correct implementation

Time = function() {

};

Time.prototype.today = function() { return "today" };
Time.prototype.tomorrow = function() { return "tomorrow" };

Output

2 passed, 0 failed, 0 skipped, took 1.19 seconds.

Now I'm not sure about you guys, but that's pretty awesome. We are testing javascript using familiar tools (NUnit and TestDriven.net) and I am running the tests directly within my IDE without any alt-tabbing!

Check out the code

author: Patrick | posted @ Wednesday, December 03, 2008 3:46 PM | Feedback (1)

Test Driven Development with Javascript


I am in love with test driven development (TDD) and I have a streamlined workflow for developing C# applications...

We use Visual Studio 2008 with TestDriven.net and I love the ability to right click my test project/test class and run the tests located automatically without having to leave my IDE.

Well... we're currently working on a lot of web related projects and unit testing javascript is a pain in the ass to say the least. There are frameworks out there, but I don't like them. I am not a big Not Invented Here (NIH) type guy, but I just didn't like having to run my tests from a browser... so today, I decided to solve the issue. Or at least start to solve it.

My goals were the following:

1. Leverage NUnit and TestDriven.net as much as possible to preserve IDE integration. I do not want to leave my IDE

2. Be able to unit test javascripts very easily

3. Provide easy to trace error messages.

4. Speed

Most javascript unit testing frameworks leverage the web browser and my solution is no different, I do however want this to be an integrated testing enviornment for .NET so the solution is as follows

1. I created a c# project that references the NUnit framework. I have created an abstract test class called JavascriptTest which has a [TestFixture] attribute applied. This class will serve as a base for the actual Test class which will be provided by the client. This base class contains a reference to a collection of scripts which will be run. More about this later.

JavascriptTest has a single [Test] which will be run by NUnit. When this test is run, it creates a JavascriptHost (more about this later) and passes it the scripts we want to run. the JavascriptHost class runs the scripts and returns a result which we then pass on to Nunit.

2. The JavascriptHost class is a subclass of System.Windows.Forms.Form. Upon creation it adds a WebBrowser control to it's child controls. We have marked the JavascriptHost class ComVisible so that it can interact with the WebBrowser control via window.external (this is set using the ObjectForScripting property on the WebBrowser). The host provides several callback methods that Javascript can use to call into .NET.

When the JavascriptHost's RunScripts method is called (by the JavascriptTest class)  it generates a dynamic html string that is a basic page template with all of the scripts to run below the ending </body> tag. As soon as the WebBrowser is ready, it calls a javascript method called "runTests" using the InvokeScript method on the WebBrowser. The runTests method triggers the test running and javascript calls back into our host using window.external to report script errors, test passes or failures, etc.

3. To actually test this out, I created another unit test project which would be the actual test project used to test our web scripts. The unit test project has a single class called TestRunner which just inherits from JavascriptTest and has a [TestFixture] decoration. Each test is located in a javascript file in this project which is set to be an Embedded Resource. The JavascriptTest class will load these scripts at test time.

More info on the script process

Thinking about our testing process from the perspective of a webbrowser, we basically want the following to happen

1. Add a small javascript at the very beginning of the page to detect parsing errors in subsequently loaded scripts. This is important because if the client's test scripts or code scripts contain errors, we won't be able to run the tests, and we want to notify the user where exactly the errors are located.

2. Add framework scripts immediately after. Framework scripts provide the unit testing framework that the user's javascript tests will utilize. These are functions such as assert.areEqual etc.

3. Add the code scripts. Code scripts are the actual code being tested. We have to add these before we add the test scripts because the test scripts will reference the code scripts.

4. Finally, add the actual test scripts which reference both the test framework as well as the code scripts.

Our javascript unit testing framework does not add links to the script files, but actually loads the files themselves and injects their text into the test page. This makes the testing process much easier.

There is more I want to write about this, but why don't you download the code so far and take a look.

 

Note: You may have to fix your NUnit references. Also - you will have to change the path in the file Tester.cs to point to your js folder in the web project. This is a work in progress so the code is sloppy, but it works with TestDriven.net so I'm happy so far.

author: Patrick | posted @ Tuesday, December 02, 2008 6:10 PM | Feedback (8)

Sample Code for Linq to NHibernate Repository


As per a request, I am providing code for both my in memory testing repository as well as my sql server based NHibernate repository so you can see how I have used Linq-to-NHibernate to create a testable interface and a real implementation that will both work under the same code.

 

First up is our Persistent base, this isn't really necessary but it saves me some time as I don't have to put an ID field into all our Persistent classes and it allows me to restrict what we can put in our repositories

    public abstract class Persistent
    {
        public int ID { get; set; }
        
        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != this.GetType()) return false;
            Persistent comp = (Persistent)obj;
            if (comp.ID == 0 && this.ID == 0) return object.ReferenceEquals(this, comp);
            return comp.ID == this.ID;
        }
    }

Now for our Repository interfaces. Notice I don't use the I prefix for interfaces, I am starting to lean away from that practice and going to a more java-like approach of naming things nicely.


    public interface Repository
    {
        RepositorySession OpenSession();
    }

    public interface RepositorySession : IDisposable
    {
        IQueryable Query() where T : Persistent;
        void Save(Persistent e);
        void Delete(Persistent e);
    }

I think the interfaces are straightforward enough. We use a session based approach as opposed to a single Repository interface that has all the methods. The idea is that Repositories hold info about connecting to the database and the session itself is similar to a Connection object in ADO.NET. That is why we've inherited from IDisposable

Now for our InMemoryRepository

    public class InMemoryRepository : Repository, RepositorySession
    {
        private List database;
        private int nextID = 1;

        public InMemoryRepository(params Persistent[] seeds)
        {
            database = new List();
            seeds.Each(s => Save(s));
        }

        public T Get(int id) where T : Persistent
        {
            return (T)database.FirstOrDefault(e => e.ID == id && (TypeCheck(e)));
        }

        public void Save(Persistent e)
        {
            database.RemoveAll(ent => ent.ID == e.ID);
            if (e.ID == 0) e.ID = nextID++;
            database.Add(e);
            foreach (PropertyInfo property in e.GetType().GetProperties())
            {
                Type pt = property.PropertyType;
                if (pt.IsSubclassOf(typeof(Persistent)))
                {
                    Persistent prop = (Persistent)property.GetValue(e, null);
                    if (prop != null && !database.Contains(prop))
                        Save(prop);
                }
                else if (pt.GetInterfaces().Contains(typeof(IEnumerable)) && pt.IsGenericType && (pt.GetGenericArguments()[0] == typeof(Persistent) || pt.GetGenericArguments()[0].IsSubclassOf(typeof(Persistent))))
                {
                    foreach (Persistent child in (IEnumerable)property.GetValue(e, null))
                    {
                        if (child != null && !database.Contains(child))
                            Save(child);
                    }
                }
            }
        }

        public void Delete() where T : Persistent
        {
            database.RemoveAll(TypeCheck);
        }

        public void Delete(Persistent e)
        {
            database.RemoveAll(ent => ent.ID == e.ID);
        }

        public IQueryable Query() where T : Persistent
        {
            return database.Where(TypeCheck).Cast().AsQueryable();
        }

        private bool TypeCheck(Persistent e)
        {
            return e.GetType() == typeof(T) || e.GetType().IsSubclassOf(typeof(T));
        }

        public RepositorySession OpenSession()
        {
            return this;
        }

        public void Dispose()
        {
        }
    }

For the most part it is pretty straightforward with a little reflection being used when we save a Persistent object to check if it has any properties that reference Persistents or collections of Persistents and then we chain the Save to them.

Note that this class was developed via TDD so it may not be feature complete for everyone but all our tests in the app we are currently working on pass so it may grow some more over time.

Finally, here is our SqlServerRepository (based on NHibernate)- you will notice that it has much less code than the inmemory one.

  public class SqlServerRepository : Repository
    {
        private string serverName;
        private string databaseName;
        private ISessionFactory sessionFactory;

        public SqlServerRepository(string serverName, string databaseName)
        {
            this.serverName = serverName;
            this.databaseName = databaseName;
        }

        private void BuildSessionFactory()
        {
            NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
            cfg.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
            cfg.Properties["dialect"] = "NHibernate.Dialect.MsSql2005Dialect";
            cfg.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
            cfg.Properties["connection.connection_string"] = GetConnectionString();
            cfg.Properties["query.substitutions"] = "true 1, false 0";
            cfg.AddAssembly(System.Reflection.Assembly.GetExecutingAssembly());
            sessionFactory = cfg.BuildSessionFactory();
            
            SchemaManager schemaManager = new SchemaManager(this.serverName, this.databaseName, cfg);
            schemaManager.Sync();
        }

        private string GetConnectionString()
        {
            return String.Format("Data Source={0}; Initial Catalog={1}; Integrated Security=SSPI;", this.serverName, this.databaseName);
        }

        #region Repository Members

        public RepositorySession OpenSession()
        {
            if (this.sessionFactory == null)
            {
                BuildSessionFactory();
            }
            return new SqlServerRepositorySession(sessionFactory.OpenSession());
        }

        #endregion
    }

    public class SqlServerRepositorySession : RepositorySession
    {
        private ISession session;

        public SqlServerRepositorySession(ISession session)
        {
            this.session = session;
        }

        #region RepositorySession Members

        public IQueryable Query() where T : Persistent
        {
            return this.session.Linq();
        }

        public void Save(Persistent e)
        {
            this.session.SaveOrUpdate(e);
            this.session.Flush();
        }

        public void Delete(Persistent e)
        {
            this.session.Delete(e);
            this.session.Flush();
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            this.session.Close();
        }

        #endregion
    }

That's about it. We love this approach and it's been awesome for testing. In order to test against a live database, just change your unit tests to utilize an SqlServerRepository and a local DB. This could be done via a config file or by using a base test class for all your tests that hit a Repository and then just changing that class to decide which Repository implementation to use.

One other thing which we do currently is separate our unit tests into fast and slow projects. Tests which go against a real database sit in the slow tests project and the rest go into the fast tests project. 99% of the time we only run our fast tests and then once in a while we'll run the slow to make sure they aren't broken.

As far as using Linq-to-NHibernate in a production environment, I have no qualms about it. It's really only a thin layer on top of NHibernate which is a very stable mapper.

author: Patrick | posted @ Monday, December 01, 2008 9:09 AM | Feedback (3)

Linq-to-NHibernate


I am what you might call... a lazy developer. But I also used to have a bad case of "not invented here syndrome". Anyways... I'm always working on improving my default architecture that I use in the line of applications I develop. I recently found Linq to NHibernate and a light went off in my head regarding this, the repository pattern, and unit testing.

In previous (successful) apps, I've done unit testing with a local instance of SQL Server or sometimes SQLite. Now all the big TDD people always say mock database access (e.g. using a repository), but I found that testing with local MSDE/SQL Express has been fine. Anyways... I wanted to improve my skills and "forget about the database" so that I can focus on the domain model like all good agilers do. So where am I headed with this...?

Repository pattern - so we want to mock the database by using an in memory counterpart, but at the same time, I know in the back of my head that I will be using a database in the end, so I dont' want to stray too far from what I will be implementing using NHibernate...

All repositories are going to have three responsibilities - Saving, Searching, and Deleting. Saving and Deleting are easy to mock. Let's for the sake of argument define a repository interface

interface IRepository
{
void Save(Entity e);
void Delete(Entity e);
T Get<T>(int id) where T : Entity;
?? Find(??);
}

In our in-memory repository, Save, Delete, and Get are very easy to implement. Save will add the entity to some internal list of entities and Delete will remove that entity. Get will do a search based on the T type parameter and the id to return the correct entity or null.

Our NHibernate implementation will be equally easy and will simply delegate most of the work to the ISession interface.

The real question comes with searching... how do we implement Find to be generic... if we use HQL we have to create a parser for our in memory implementation but the NHibernate implementation will be easy. If we use the NHibernate criteria API, we still have to implement a lot of work on the in memory side. If we use query objects we have a lot of work to do. Each query will need to be interpreted by the correct repository implementation. This is where LINQ comes in and Linq-to-NHibernate/Linq-to-objects...

Let's refine our IRepository interface to this

interface IRepository
{
void Save(Entity e);
void Delete(Entity e);
T Get<T>(int id) where T : Entity;
IQueryable<T> Query<T>();
}

Our in memory representation is going to simply generate an IEnumerable<T> representing the objects of the type parameter T and use the extension method AsQueryable to return the actual IQueryable interface

Our NHibernate implementation will use Linq-to-NHibernate and the extension method on our ISession provided to return the same IQueryable<T>

What is great about this is now we can create a set fo DAOs that will operate on the IQueryable using the Expression tree as our "query object".

So for example, let's say we want to get a user matching a specific email address, we can create a class called UserDao for example

class UserDao
{
      User GetByEmailAddress(string emailAddress) { return repository.Query<User>().Where(u => u.EmailAddress == emailAddress).FirstOrDefault(); }
}

Now, I don't like creating a Dao for every type of Entity so instead, what I have done is created an extension class that provides any Finder methods that our repository will need...

public static class Dao
{
     public static User GetByEmailAddress(this IQueryable<User> users, string emailAddress)
     {
           return users.Where(u => u.EmailAddress == emailAddress).FirstOrDefault();
     }
}

And now I can use this code somewhere

User user = repository.Query<User>().GetByEmailAddress("patrick.greene@evot.net");
 

And it will work with either in memory OR NHibernate implementations. All we have to do is make a small NHibernate repository implementation. We also use a config setting in our App.config to specify whether we use in memory or NHibernate repository. Then we can do an integration test to make sure all our mapping files and db are correct simply by changing the config file for our unit tests to use NHibernateRepository as opposed to InMemoryRepository. All the tests which ran nicely on our in  memory should run with NHibernate when our mapping files are correct.

 

Overall it's a pretty kick ass approach for TDD

author: Patrick | posted @ Wednesday, July 16, 2008 2:57 PM | Feedback (2)

PostSharp AOP


We are starting the next release of our corporate flagship product (a call center application) and being a lone wolf developer, I was looking for an AOP solution for c# that will reduce logging, transaction, and other "cross-cutting" code.

I stumbled upon www.postsharp.org and I have to admit, I am extremely impressed. I went through the short video tutorial located here and was instantly hooked. I can already envision all the log4net code I will no longer be writing.

I can add this to our default architecture along with nHibernate, log4net, and Linq-to-NHibernate (thanks Ayende)

author: Patrick | posted @ Wednesday, July 16, 2008 2:29 PM | Feedback (0)