Archive for July, 2007

Introduction to Dependency Injection

3 commentsWritten on July 31st, 2007 by
Categories: Dependency Injection, Software Development, testing

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 :)

The Birth Of Noma

No Comments »Written on July 30th, 2007 by
Categories: Uncategorized

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 :)

ReSharper 3.0

2 commentsWritten on July 29th, 2007 by
Categories: Software Development

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.

Tool to analyze NHibernate mappings

6 commentsWritten on July 25th, 2007 by
Categories: NHibernate, Software Development

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 :)

CopySourceAsHtml

No Comments »Written on July 23rd, 2007 by
Categories: About The Blog

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.