Simple NHibernate Example utilizing various xDD Techniques, Part 1


I wanted to present a simple NHibernate example utilizing some techniques I’ve learned along the way. This first post will provide some domain level background.

Let me know if you have any feedback, so that I can correct or extend this example.

Domain Driven Design

From Eric Evan’s “Domain-Driven Design: Tackling Complexity in the Heart of Software,” I will use the concept of the Ubiquituous Language to derive a Model-Driven Design. That is, begin by taking a common language between the domain experts and developers. Then translate the language into an abstract representation, the domain model.

As developers, we can derive our implementation from the domain model and still converse with domain experts and users in terms of the ubiquitous language and not through technical “mumbo-jumbo”. Well, most of the time.

Starting with a very, very simple example, we might have the following conversation between a domain expert and developer:

Domain Expert: “I would like the system to take in a lead.”

Developer: “You mean store a person’s information in the database?”

Domain Expert: “A database? Sure, if that makes sense. All I really need is for you to save the lead’s information somehwere; first name, last name, and email address. Can you do that?”

And that’s it for now. Yes, I know that’s pretty dang simple. I’ll break this down a little.

The domain expert refers to two Domain-Driven Design (DDD) concepts. I will not into great detail regarding these two concepts since the DDD book does a great job (or have a look at this good introductory book, “Domain-Driven Design Quickly”):

  1. The first concept is that of an Entity, which in this case, I only have one. I will refer to the known entity as a Lead.
  2. The second concept is that of the Repository. The Lead will be saved “somewhere.” I will use a LeadRepository to save the Lead. Repositories allow for the storage and retrieval of entities.

I would also note that there is the concept of a Factory implied in this story, but I will not go into that for now. Also, I am not going to draw any UML models as this example is ridiculously easy and because I’m lazy.

Test Driven Development

I am not familiar enough with Behavior-Driven Development (BDD) to fully utilize the technique in this example. I will stick to Test Driven Development (TDD). I am going to assume that you know enough about TDD, so I’ll begin by implementing the Lead entity.

We know that we have to capture the Lead’s first name, last name and email. So I’ll write some very simple, yet necessary, tests.

Here are the tests (UPDATED: 3/11/2007):

using Foo.Domain;
using NUnit.Framework;
 
namespace Tests.Foo.Domain
{
    [TestFixture]
    public class WhenSettingUpANewLead
    {
        private Lead lead;
 
        [SetUp]
        public void SetUpContext()
        {
            lead = new Lead();   
        }
 
        [Test]
        public void ShouldAllowFirstNameToBeCaptured()
        {
            lead.FirstName = "Foo";
            Assert.AreEqual("Foo", lead.FirstName, "First Name was not captured.");
        }
 
        [Test]
        public void ShouldAllowLastNameToBeCaptured()
        {
            lead.LastName = "Bar";
            Assert.AreEqual("Bar", lead.LastName, "Last Name was not captured.");
        }
 
        [Test]
        public void ShouldAllowEmailToBeCaptured()
        {
            lead.Email = "[email protected]";
            Assert.AreEqual("[email protected]", lead.Email, "Email was not captured.");
        }
    }
}

And the resulting entity class:

namespace Foo.Domain
{
    public class Lead
    {
        private string firstName;
        private string lastName;
        private string email;
 
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
 
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
 
        public string Email
        {
            get { return email; }
            set { email = value; }
        }
    }
}

 

Simple enough! The interesting repository stuff will come in the next post, I promise. 🙂