The Inquisitive Coder - Davy Brion’s Blog

Trying to walk that thin line between intelligence and ignorance

Archive for July, 2007

Introduction to Dependency Injection

Posted by Davy Brion on 31st July 2007

Dependency Injection (DI) is an incredibly useful and easy technique which makes your code a lot easier to test (that’s not the only benefit though). But i’ve noticed that there are still plenty of developers who don’t know what it is, or have heard of it but don’t know how to use it, etc… Hopefully, it’ll be somewhat clear after reading this :)

I like to use ‘real’ examples so i’ll try to explain DI based on some code i wrote for Noma yesterday. I have a SqlMetaDataProvider class which needs to provide me with meta data coming from a SQL Server database. It retrieves the meta data from the database in a relational structure (a DataSet) and then converts it to an easy to use object model. Obviously, i want to be able to test this class without actually going to the database because that would make my tests slow. So how can we test if the relational data is being converted to the object model without going to the database?

Well, let’s look at what the class does. First of all, it retrieves sql server meta data. Then it converts it to an object model. But retrieving the meta data doesn’t really belong here… it should be functionality that’s offered by another class. So we create a SqlDataRetriever class. All it will do is return meta data in the relational structure. Nothing more. So now, our SqlMetaDataProvider class can simply use the SqlDataRetriever class to retrieve the meta data. So basically, SqlDataRetriever is now a dependency of the SqlMetaDataProvider class because SqlMetaDataProvider is depending on SqlDataRetriever to return the relational meta data.

At this point, our class could look like this:

    public class SqlMetaDataProvider : IMetaDataProvider
    {
        private readonly string _connectionString;
        private readonly SqlDataRetriever _sqlDataRetriever;
 
        public SqlMetaDataProvider(string connectionString)
        {
            _connectionString = connectionString;
            _sqlDataRetriever = new SqlDataRetriever();
        }
 
        public MetaDataStore GetMetaDataStore()
        {
            SqlMetaData sqlMetaData = _sqlDataRetriever.GetMetaData(_connectionString);
 
            return ConvertToMetaDataStore(sqlMetaData);
        }
 
        private MetaDataStore ConvertToMetaDataStore(SqlMetaData sqlMetaData)
        {
            MetaDataStore store = new MetaDataStore();
 
            AddTablesToStore(sqlMetaData.TableInfo, store);
            AddColumnsToTablesInStore(sqlMetaData.ColumnInfo, store);
            CreateRelationshipsBetweenTables(sqlMetaData.RelationshipInfo, store);
 
            return store;
        }
    }

Note: I left out the code for the AddTablesToStore, AddColumnsToTablesInStore and CreateRelationshipsBetweenTables methods because they aren’t relevant to this specific topic.

Now we need to make sure we can replace the instance of SqlDataRetriever during testing with one we can supply ourselves. That test instance could then simply return a DataSet that was created in-memory, thus keeping our tests running fast. Notice how SqlMetaDataProvider has a reference of the type SqlDataRetriever. The type is essentially fixed, which creates a strong dependency on the SqlDataRetriever class. If we were to replace the type of the reference with an interface, it would at least make it easier to use another type for our required dependency, one that simply implements the interface.

So we create the ISqlDataRetriever interface:

    public interface ISqlDataRetriever
    {
        SqlMetaData GetMetaData(string connectionString);
    }

And then we modify the definition of SqlDataRetriever to implement the interface:

    public class SqlDataRetriever : ISqlDataRetriever

Now we need to modify our SqlMetaDataProvider class so it holds a reference to the interface type, instead of the class type:

        private readonly ISqlDataRetriever _sqlDataRetriever;

We still need to find a way to inject our dependency into our SqlMetaDataProvider so we’ll modify the constructor:

        public SqlMetaDataProvider(string connectionString, ISqlDataRetriever sqlDataRetriever)
        {
            _connectionString = connectionString;
            _sqlDataRetriever = sqlDataRetriever;
        }

The only downside to this is that it now takes more work to create an instance of SqlMetaDataProvider… work that clients shouldn’t need to do if they just want to use the default ISqlDataRetriever implementation. If you’re using an Inversion Of Control (IoC) container, you can simply request an instance of SqlMetaDataProvider and the IoC container would also create the necessary dependency for you. Using an IoC container however is outside of the scope for this post, so we won’t do that. In fact, if you know that your production code will always use the SqlDataRetriever implementation, you could also provide a simpler constructor which takes care of that for you:

        public SqlMetaDataProvider(string connectionString)
            : this(connectionString, new SqlDataRetriever()) {}

So you could use the simpler constructor in your production code, and the other one in your test code. Speaking of test code, we still need to write that test which tests the conversion without hitting the database. First, we need to create an implementation of ISqlDataRetriever which allows us to pass a DataSet to it which the ISqlDataRetriever instance should return to its consumer (our SqlMetaDataProvider):

    public class SqlDataProviderStub : ISqlDataRetriever
    {
        private SqlMetaData _sqlMetaData;
 
        public SqlMetaData SqlMetaData
        {
            set { _sqlMetaData = value; }
        }
 
        SqlMetaData ISqlDataRetriever.GetMetaData(string connectionString)
        {
            return _sqlMetaData;
        }
    }

And finally, the test:

        [Test]
        public void GetMetaDataStore_ProvideDataSetWithTwoTablesAndRelationship_MetaDataStoreIsCorrect()
        {
            SqlMetaData sqlMetaData = PrepareMetaDataSetInMemoryWithTestData();
 
            SqlDataProviderStub sqlDataProvider = new SqlDataProviderStub();
            sqlDataProvider.SqlMetaData = sqlMetaData;
 
            // pass null as the connectionString, and pass our SqlDataProviderStub
            IMetaDataProvider metaDataProvider = new SqlMetaDataProvider(null, sqlDataProvider);
 
            MetaDataStore store = metaDataProvider.GetMetaDataStore();
 
            AssertStoreContainsOurTestData(store);
        }

Mission accomplished :)

Share/Save/Bookmark

Posted in Dependency Injection, Software Development, Test Driven Development | 3 Comments »

The Birth Of Noma

Posted by Davy Brion on 30th July 2007

As i mentioned earlier, i will be developing a tool to analyze NHibernate mapping files. Somewhat like how FxCop analyzes code, this tool will analyze your mapping files and compare them to database metadata and class metadata to spot errors, show warnings, or suggest improvements.

The SourceForge people finally activated my project so i guess it’s somewhat official now… The tool will be called Noma. Yes that’s right… Noma. And no, the name has no meaning whatsoever. If anything, it’s merely a testament to my inability to come with a good project name.

The project page can be found here and the SVN repository can be found here. There’s very little code in there so far, but that should improve soon :)

Share/Save/Bookmark

Posted in Uncategorized | No Comments »

ReSharper 3.0

Posted by Davy Brion on 29th July 2007

I finally tried ReSharper 3.0 a couple of days ago… i was a little hesitant at first because of the price ($150 for the C# edition). But after about 15 minutes of trying it out, i knew enough… it was worth the money.

This tool is simply amazing… things i like most:

  • The refactoring options are extremely good… much better than what visual studio offers
  • Dynamic code analysis… it just analyzes your code and suggests improvements or notifies you of errors while you’re coding, and somehow it manages to do this without getting on my nerves (not an easy task, trust me)
  • Highly configurable auto-formatting of code… there’s a ton of options you can configure for this auto-formatting. I found options for all of my little pet-peeves when it comes to code formatting (and I got a lot of those…)
  • Really makes it easy to keep your code nice and clean
  • Just an all-round productivity booster

What i didn’t like:

  • By default, it offers you its own IntelliSense… after a few hours of trying to get used to it i switched back to Visual Studio’s default IntelliSense. ReSharper’s IntelliSense kinda felt buggy to me, or perhaps i just didn’t ‘get’ it. Either way, it was easy to disable.
  • Slower Visual Studio startup speed… it does take a little bit longer for Visual Studio to start up now, but compared to the time you save while coding, this is actually meaningless

So, i’d definitely recommend trying it out… you can use it for 30 days without paying for it. If you still don’t feel it’s worth the money after that, you can uninstall it. Allthough i really can’t imagine using this for 30 days, and then getting used to a default Visual Studio again.

Share/Save/Bookmark

Posted in Software Development | 2 Comments »

Tool to analyze NHibernate mappings

Posted by Davy Brion on 25th July 2007

I just submitted a project registration at sourceforge for a new tool that will analyze your nhibernate mappings. The application should at least be able to do the following things:

  • Validate the .hbm.xml files against the official NHibernate mapping XSD. Obviously, Visual Studio can do this for you while you’re editing the files but new users often forget to enable this in Visual Studio and make a lot of mistakes this way.
  • Compare your mapping files to the metadata in the database and report any errors between these two. Initially only SQL Server and Oracle will be supported.
  • Compare your mapping files to their respective .NET classes and report any errors between these two.
  • Not only report errors, but suggest improvements/optimalisations that should result in a better NHibernate experience

The application will obviously be open source, most likely released under the LGPL.

If you have any suggestions for this tool, please let me know :)

Share/Save/Bookmark

Posted in NHibernate, Software Development | 6 Comments »

CopySourceAsHtml

Posted by Davy Brion on 23rd July 2007

Formatting code or xml for your blog can really be a pain… but not anymore, thanks to the excellent CopySourceAsHtml plugin for Visual Studio. This allows you to simply select some code, right-click and select Copy As Html. Then simply paste the result where you need to put the html… very easy, very nice.

Note to Parallels users… you need to disable the clipboard features of Parallels Tools to get it working. If you don’t you’ll get an exception everytime you try to use Copy As Html.

Share/Save/Bookmark

Posted in About The Blog | No Comments »

More on NHibernate and ITransactionFactory

Posted by Davy Brion on 21st July 2007

A while ago i submitted a patch to fix the issue i had with NHibernate ignoring the hibernate.transaction_factory setting. The patch has now been committed to the NHibernate subversion repository. The name of the setting has been changed to hibernate.transaction.factory_class though.

So now you can define which ITransactionFactory you want NHibernate to use in your config file, or from code without using my dirty reflection workaround as this test demonstrates:

    [Test]
    public void SettingsTransactionFactoryReturnsConfiguredTransactionFactory()
    {
      Configuration configuration = new Configuration();
      configuration.Properties[Cfg.Environment.TransactionStrategy] =
        "NHibernate.Test.NHSpecificTest.NH1054.DummyTransactionFactory, "
        + this.GetType().Assembly.FullName;

      ISessionFactory sessionFactory = configuration.BuildSessionFactory();

      Assert.IsInstanceOfType(typeof(DummyTransactionFactory),
        sessionFactory.Settings.TransactionFactory);
    }

To avoid any confusion: Cfg.Environment.TransactionStrategy is a public string containing “hibernate.transaction.factory_class”

You will need either NHibernate from trunk to use this, or wait for the 1.2.1 release.

Share/Save/Bookmark

Posted in NHibernate, Software Development | 2 Comments »

Native ID generation with NHibernate

Posted by Davy Brion on 17th July 2007

i was looking for a way to define the mapping of an ID field so it would work on both Oracle and SQL Server… In case of Oracle, it would have to use a Sequence that i can define. On Sql Server, it should use an Identity column. Luckily, NHibernate offers just that… the ‘native’ ID generator uses identity on sql server and a sequence on Oracle.

Unfortunately the ‘native’ generator is hardly documented in the Nhibernate reference documentation so it wasn’t really clear to me which sequence would be used, or how i could define my own. All the documentation says is basically:

For cross-platform development, the native strategy will choose from the identity, sequence and hilo strategies, dependent upon the capabilities of the underlying database.

So how can you define which sequence it should use in case of Oracle? Very simple actually… turns out you just define the sequence name in the same way you would as if you set it to use the ’sequence’ generator.

So here’s how you do it:

    <id name="Id" column="CustomerId" type="long" unsaved-value="-1"
        access="field.camelcase-underscore">
      <generator class="native" >
        <param name="sequence">sq_customer</param>
      </generator>
    </id>

On Oracle, it will use the sq_customer sequence whereas on SQL Server the sequence parameter will be ignored and it will use the Identity setting of the column that was defined as the ID (in this case, CustomerId’s Identity settings)

Share/Save/Bookmark

Posted in NHibernate, Software Development | 3 Comments »

NHibernate Mapping Examples

Posted by Davy Brion on 15th July 2007

When you’re starting out with NHibernate, it’s sometimes hard to find good examples. Most examples online are too simple, or are incomplete (just the mappings, but no code for instance). It’s always easier if you have some examples that are large enough, but still small enough to be easy to grasp. So i created mappings and classes for the Northwind tables. I figured this could be useful reference material for anyone new to NHibernate so i’m making the whole thing available for everyone. You’ll find examples of one-to-many, many-to-one and many-to-many associations in there. I used a couple of different cascade options for the associations, depending on the constraints on the tables. I’ve also included about 60 unit tests to verify the mappings are working correctly. These tests should also give you a good idea about how NHibernate deals with certain mappings and options.

I did modify the Northwind database here and there… the zip file contains all the sql create scripts. This is what my version looks like:

Northwind Table Diagram

And the class diagram looks like this:

Northwind Class Diagram

I do want to make it clear that this is just an example. I’m not saying that this how you should map your objects and their associations to tables and their relationships. I pretty much provided every possible association in this example, whereas on a real project i’d only create the associations that i actaully need to implement the required functionality. But for the purpose of this example, i thought it would be a good idea to provide as much as possible.

You can download it here

Share/Save/Bookmark

Posted in NHibernate, Software Development | 26 Comments »

Visual Studio 2008 release date

Posted by Davy Brion on 12th July 2007

In case you didn’t know already, Visual Studio 2008, SQL Server 2008 and Windows Server 2008 will all be released on February 27th, 2008.

More info can be found here

i kinda hoped Visual Studio 2008 would be released sooner (like November 2007 or so) but alas…

Share/Save/Bookmark

Posted in Software Development | 1 Comment »

Implementing a Value Object

Posted by Davy Brion on 8th July 2007

A Value Object (also known as Immutable Object) is basically an object without a conceptual identity. A Value Object is defined through its inner values, and not an identity like Entity Objects. This means that a Value Object’s inner values can not be changed after object creation, hence the term Immutable Object. Should you need to change the inner values of the Value Object, you should actually create a new Value Object.

For some of you, this might seem odd. But you’ve actually used Value Objects on many occassions already. In .NET, strings are Value Objects. So are DateTime instances. If you create a string, you can’t modify its inner value. If you do, a new string is actually created. Same thing with a DateTime. The DateTime class provides methods to add days, hours, seconds, whatever… but those methods never modify the instance’s inner value. Instead, they return a new DateTime object because each DateTime instance is immutable.

This also has interesting consequences on object equality. Two Value Objects holding the same data should be considered identical objects, even though they point to different memory locations.

Value Objects are great and can make a lot of things much easier for you. In this post, i’m going to show you how you can easily create a true Value Object while avoiding some common pitfalls.

For this example, i’m going to create an Address class. An Address instance needs to hold some data (street, city, region, postalcode, country, phone number). This data can often be identical between other Entity objects. Maybe I have a Person class which needs to hold an Address. Two people living in the same house would have the same physical address. Both Person instances should then have the same Address too. Husband.Address.Equals(Wife.Address) should return true without having to worry about some unnecessary identity of the Address instances.

This is how our first implementation of the Address class would look like:

  public class Address
  {
    public Address(string street, string city, string region,
      string postalCode, string country, string phoneNumber)
    {
      _street = StringValueOrEmptyString(street);
      _city = StringValueOrEmptyString(city);
      _region = StringValueOrEmptyString(region);
      _postalCode = StringValueOrEmptyString(postalCode);
      _country = StringValueOrEmptyString(country);
      _phoneNumber = StringValueOrEmptyString(phoneNumber);
    }

    private string StringValueOrEmptyString(string value)
    {
      return (value != null ? value : string.Empty);
    }

    private string _street;

    public string Street
    {
      get { return _street; }
    }

    private string _city;

    public string City
    {
      get { return _city; }
    }

    private string _region;

    public string Region
    {
      get { return _region; }
    }

    private string _postalCode;

    public string PostalCode
    {
      get { return _postalCode; }
    }

    private string _country;

    public string Country
    {
      get { return _country; }
    }

    private string _phoneNumber;

    public string PhoneNumber
    {
      get { return _phoneNumber; }
    }
  }
}

So now an Address instance’s values can not be changed after object creation. By the way, in case you’re wondering why i assign string.Empty instead of allowing null references to my fields: it’s because i want to avoid checking for null every time i want to use my fields later on in my code. This is known as the Null Object Pattern.

Now we have to make sure that 2 Address instances holding the same data are actually recognized as equal objects. First, we’ll override the Equals method:

    public override bool Equals(object obj)
    {
      Address address = obj as Address;

      if (address != null)
      {
        return
          _street.Equals(address.Street) &&
          _city.Equals(address.City) &&
          _region.Equals(address.Region) &&
          _postalCode.Equals(address.PostalCode) &&
          _country.Equals(address.Country) &&
          _phoneNumber.Equals(address.PhoneNumber);
      }

      return base.Equals(obj);
    }

Thanks to the Null Object Pattern, i don’t need null checks when accessing my fields which is great because i really dislike null checks all over the place. Anyway, back to the subject at hand: Equals will return true if the values of the instances are identical.

If you override the Equals method, you really should override the GetHashCode() method as well:

    public override int GetHashCode()
    {
      return _street.GetHashCode() ^
           _city.GetHashCode() ^
           _region.GetHashCode() ^
           _postalCode.GetHashCode() ^
           _country.GetHashCode() ^
           _phoneNumber.GetHashCode();
    }

Ok, our Address instances will behave properly when they are compared with the Equals method. A lot of developers prefer to use the == and != operators though, so we should make sure that these operators also compare the actual values instead of the default reference equality check. For that, we’ll simply overload the operators:

    public static bool operator ==(Address address1,
      Address address2)
    {
      if (!object.ReferenceEquals(address1, null) &&
        object.ReferenceEquals(address2, null))
      {
        return false;
      }

      if (object.ReferenceEquals(address1, null) &&
        !object.ReferenceEquals(address2, null))
      {
        return false;
      }

      return address1.Equals(address2);
    }

    public static bool operator !=(Address address1,
      Address address2)
    {
      return !(address1 == address2);
    }

In the == overload, we need to check if the values we’ve received aren’t null. If one of them is null, and the other isn’t, then they obviously can’t be equal. But how are you going to check if they’re null? You can’t use address1 == null or adress2 == null because then you’d go straight back into this == overload which would cause a stack overflow. So we use Object.ReferenceEquals() to do the check for us. If neither of the objects is null, we simply return the result of calling the Equals method.

We now have a true Value Object. Its values are immutable, and the instances will behave properly when checked for equality. The following tests all pass:

  [TestFixture]
  public class AddressTests
  {
    private string _defaultStreet = "MyStreet 243";
    private string _defaultCity = "MyCity";
    private string _defaultRegion = "MyRegion";
    private string _defaultPostalCode = "12345";
    private string _defaultCountry = "MyCountry";
    private string _defaultPhoneNumber = "123-4567-89";

    [Test]
    public void TwoInstancesWithSameDataAreEqual()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.AreEqual(address1, address2);
      Assert.That(address1 == address2);
    }

    [Test]
    public void TwoInstancesWithDifferentDataAreNotEqual()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = new Address(_defaultStreet + "2", _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);

      Assert.AreNotEqual(address1, address2);
      Assert.That(address1 != address2);
    }

    [Test]
    public void NullAddressReferenceDoesntCrashWhenUsingEqualityOperator()
    {
      Address address1 = null;
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.That(address1 != address2);
    }

    [Test]
    public void TwoInstancesWithSameDateReturnSameHashCode()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.AreEqual(address1.GetHashCode(), address2.GetHashCode());
    }

    [Test]
    public void TwoInstancesWithDifferentDataDoNotReturnSameHashCode()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = new Address(_defaultStreet + "2", _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);

      Assert.AreNotEqual(address1.GetHashCode(), address2.GetHashCode());
    }

    private Address CreateTestAddressWithDefaultData()
    {
      return new Address(_defaultStreet, _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);
    }
  }

Share/Save/Bookmark

Posted in Patterns, Software Development | 4 Comments »