You are currently browsing the category archive for the ‘Uncategorized’ category.

We have been using NHibernate and using SQLite for in-memory tests which has worked very well for us but hit an issue when using schemas.

We wanted to separate out the tables used by our services through the use of schemas as schemas provides a very nice clean logical separation. However, although NHibernate supports schemas through the schema attribute on your class mappings, our SQLite tests fail as SQLite doesn’t support schemas.

We looked into ways around this. Our first port of call was to look at whether their is a way of managing this through our own NHibernate dialect class but our investigations led us to a dead end – although we plan on revisiting this later.

So we switched to looking at the SQLite ADO.NET provider. We figured that if we wrapped this then we could intercept the calls to it and override the “schema.table” requests into “schema_table”.

To achieve this we provide our own implementations of the following:

  • IDbCommand
  • IDbConnection
  • DbParameter
  • DbParameterCollection
  • IDbTransaction

Within each of these implementations we wrap the underlying System.Data.SQLite versions of these to delegate down to. Within the command itself we parse the provided CommandText and detect if a schema is used, overriding this when necessary.

The final piece of the puzzle is to provide our own NHibernate driver which will tell NHibenate to use our implementation of IDbCommand. We couldn’t just inherit from the SQLite20Driver class so we had to copy its implementation as provided below:

using NHibernate.Driver;

namespace TheAgileWorkshop.SQLiteWithSchemaSupport
{
    public class SQLiteDriver : ReflectionBasedDriver
    {
        public SQLiteDriver()
            : base(
              "TheAgileWorkshop.SQLiteWithSchemaSupport",
              "TheAgileWorkshop.SQLiteWithSchemaSupport.SQLiteWithSchemaConnection",
              "TheAgileWorkshop.SQLiteWithSchemaSupport.SQLiteWithSchemaCommand")
        {
        }

        public override bool UseNamedPrefixInSql
        {
            get { return true; }
        }

        public override bool UseNamedPrefixInParameter
        {
            get { return true; }
        }

        public override string NamedPrefix
        {
            get { return "@"; }
        }

        public override bool SupportsMultipleOpenReaders
        {
            get { return false; }
        }

        public override bool SupportsMultipleQueries
        {
            get { return true; }
        }
    }
}

 

Now to use schemas with NHibernate and keep your in-memory SQLite tests passing, reference the TheAgileWorkshop.SQLiteWithSchemaSupport.dll and specify this driver class (TheAgileWorkshop.SQLiteWithSchemaSupport.SQLiteDriver) in place of the SQLite20Driver class that exists at the moment.

To use this, you can get the source or grab a copy of a release build of the dll directly.

I hope this helps others. If there are any issues then please don’t hesitate to let me know.

Advertisements

I saw a post this morning entitled Insidious Dependencies which I recommend reading. It discusses some of the dependencies that creep in often without you realising such as depending on the file system and DateTime (DateTime.Now being the common one). At the bottom of the list is a nod towards configuration also being a dependency when tied directly to settings in web.config/app.config.

This is actually one of my bug bears and my solution to this (with the help of some IoC) is to use a configuration model with a configuration provider ‘pattern’ via an IConfigurationProvider interface like below:

public interface IConfigurationProvider<T>
{
    T GetConfiguration();
}

This then allows you to define a dependency on this interface with T being the configuration model object you are interested in. So for instance, if you have an EmailServer class that would be configured with say server name and port number then you would define an EmailServerConfiguration such as

public class EmailServerConfiguration
{
    public string ServerName;
    public int Port;
}

And then our EmailServerConfiguration would be injected into our EmailServer via our IConfigurationProvider:

public class EmailServer
{
    private readonly EmaiServerConfiguration config;

    public class EmailServer(IConfigurationProvider<EmailServerConfiguration> configProvider)
    {
        config = configProvider.GetConfiguration();
    }
}

By using this approach we are gaining a couple of things. For one we are working to a strong configuration contract rather than directly to app.config settings. I know this can be achieved using the .Net 2.0 settings but we are also gaining this ability without being directly dependent on this so we can directly inject our configuration for testing purposes.

We are also breaking a direct dependency on where we get our configuration from as we can have different implementations of the particular IConfigurationProvider so we can drive our config from app.config, our IoC container, a database or from a web service call all without changing our EmailServer class itself.

For example, our app.config using application settings directly would be something like this:

public class ApplicationSettingsBasedEmailServerConfigurationProvider
    : IConfigurationProvider<EmailServerConfiguration>
{
    public EmailServerConfiguration GetConfiguration()
    {
        EmailServerConfiguration config = new EmailServerConfiguration();
        config.ServerName = ConfigurationManager.AppSettings["EmailServerName"];
        config.Port = Int32.Parse(ConfigurationManager.AppSettings["EmailServerPort"]);
        return config;
    }
}

Whereas a Castle Windsor driven configuration (or any other DI framework) would be:

public class WindsorBasedEmailServerConfigurationProvider
    : IConfigurationProvider<EmailServerConfiguration>
{
    private readonly EmailServerConfiguration config;

    public WindsorBasedEmailServerConfigurationProvider(string emailServerName, int emailServerPort)
    {
        config = new EmailServerConfiguration { ServerName = emailServerName, Port = emailServerPort };
    }

    public EmailServerConfiguration GetConfiguration()
    {
        return config;
    }
} 

I hope from this you can see how easy it is to break the direct dependency on configuration and gain some flexibility in the process.

Just in case anyone is wondering as to the title of my blog (I don’t expect anyone is) – it is an anagram of my name, Stephen Oakman 🙂

In our last post we implemented a controller which grabbed a list of books and passed them over to the view to display them. In this post we are going to move that grabbing of a list of books into something else and see how WIndsor can help us out.

So our current list of books is retrieved as below:

   1: public void Index()
   2: {
   3:     List<Book> books = new List<Book>();
   4:     books.Add(new Book("Our First Development Book", "This is our first development book to go into our list of books"));
   5:     books.Add(new Book("The Pragmatic Programmer", "A fantastic book that is as relevant today as it was yesterday. Highly recommended."));
   6:     books.Add(new Book("Working Effectively with Legacy Code", "Another fantastic book which now applies to this application as we aren't writing tests."));
   7:     PropertyBag["books"] = books;
   8: }

We would like to refactor this so that the controller wasn’t responsible for getting this list directly but instead worked with something else to get this listing. My preferred way would be to access this list from a BookRepository like so:

   1: public void Index()
   2: {
   3:     List<Book> books = bookRepository.GetAllBooks();
   4:     PropertyBag["books"] = books;
   5: }

But where do we get bookRespository from? One way would be to new up an instance directly but doing so would hide the dependency that BookController has on BookRepository. But here we can lean on the WIndsor integration and use the Dependency Injection pattern to push our dependencies into our controller (while at the same time making it clear that our controller has a dependency on BookRepository).

Our first step is to create our new BookRepository and move our current book listing to it. It doesn’t really fit within any of the structure the Monorail wizard generated for us (although Models would be the best match) so I’m creating it under a newly added Services folder.

   1: public class BookRepository
   2: {
   3:     public IList<Book> GetAllBooks()
   4:     {
   5:         IList<Book> books = new List<Book>();
   6:         books.Add(new Book("Our First Development Book", "This is our first development book to go into our list of books"));
   7:         books.Add(new Book("The Pragmatic Programmer", "A fantastic book that is as relevant today as it was yesterday. Highly recommended."));
   8:         books.Add(new Book("Working Effectively with Legacy Code", "Another fantastic book which now applies to this application as we aren't writing tests."));
   9:         return books;
  10:     }
  11: }

Now we can add a constructor to our controller that caches the passed in BookRepository instance like so:

   1: public class BookController : BaseController
   2: {
   3:     private readonly BookRepository bookRepository;
   4:  
   5:     public BookController(BookRepository bookRepository)
   6:     {
   7:         this.bookRepository = bookRepository;
   8:     }
   9:  
  10:     public void Index()
  11:     {
  12:         List<Book> books = bookRepository.GetAllBooks();
  13:         PropertyBag["books"] = books;
  14:     }
  15: }

So now we have moved our book retrieval out into its own class and made our dependency on this new class explicit via our constructor in the controller. If we hit F5 and view our page we get a “Can’t create component ‘book.controller’ as it has dependencies to be satisfied.” error like below:

Cant create component book.controller as it has dependencies to be satisfied

The reason for this is that, as it says, the BookController depends on BookRepository which was not registered. This is because when Monorail invokes our BookController it does so through Windsor which then resolves our dependencies for us.

Registering our BookRepository is handled in a similar way to which we registered our controller by adding our new BookRepository to components.config in the config folder. All dependencies that aren’t controllers will need to be registered in this file.

If we open up components.config you will see an empty components element. In this we add a component node for our new BookRepository:

<component id="bookRepository"
	type="BookLendingService.Services.BookRepository, BookLendingService" />

Now that we have registered both our component and controller then Windsor can resolve our dependencies for us. So if we hit F5 and view our page we should now see the exact same page we had before we moved the book listing logic.

So we can start to see where the Windsor integration allows us to benefit from dependency injection. As another example we should really introduce an interface for our BookRepository and get the controller to depend on this rather than on the implementation. This allows us to easily mock our dependencies when we test our controllers.

To do this, first extract the interface from our BookRepository (with it’s only member at the moment) and then change BookRepository to implement the interface. Now update BookController to change all uses of BookRepository to IBookRepository, and finally, a change to the components.config file to add a service attribute:

<component id="bookRepository"
	service="BookLendingService.Services.IBookRepository, BookLendingService"
	type="BookLendingService.Services.BookRepository, BookLendingService" />

If you build and view the page again then we should still see our list of books as before but now we are depending on interfaces rather than our implementations.

In our next post we will lean on Windsor even more by enabling auto registration of our controllers and components/services. To do this we will also need to upgrade our Monorail assemblies to a later version which we will also cover.

I’ve had an interest in the Castle stack for a while now but I haven’t yet had a chance to use Monorail in anger. At my current contract we have been having some nice healthy discussions about development in general (principles, Microsoft’s involvement in OSS, MVC) and I’ve mentioned Monorail several times. This has happened so frequently now that I’ve managed to infect at least one person here to look into more at the weekend and at the same time I’ve now become infected as well.

I’ve been playing around with it a bit in the evenings and it feels so refreshing. Moving away from web forms is like a breath of fresh air. I’ve read about this reaction on several blogs so I knew I would feel the same but I didn’t realise just how much more free I would feel. It really is like a heavy burden being lifted from your shoulders.

Now, it is very early days but I intend to delve deeper into Monorail along with the integration with the rest of the Castle stack and will be planning on posting updates on my travels. The main stumbling block I always have is having that meaty project to base it all around. I have a plan for that so we’ll see how it goes.

In my attempts to remove even more friction from writing tests I have a new VS macro for running the tests.

I use ReSharper’s unit test runner as it significantly reduces context switch from writing the code to running it. Besides, it looks so damn sexy!! It has a Unit Test Explorer which shows you all the tests in the solution, and then a Unit Test Session where you can select groups of tests to run (and it’s tabbed so you can have different groups of tests). I use the Unit Test Session to isolate just the tests relevant to the code I’m working on.

With the previously posted BDD macro and R# templates, I get smooth flowing writing of tests but then I find myself moving to the mouse to run the tests. What I wanted to do was use shortcuts.

There is an existing shortcut in R# for showing the Unit Test Session (Ctrl+Alt+R). You can then set another shortcut for the command ReSharper_UnitTestSession_RunAll. I set Ctrl+T as the shortcut to this command.

With these 2 in place, it is reasonably quick to write test, hit Ctrl+Alt+R, Ctrl+T and see the selected tests run (including the newly written test). This is reasonably smooth.

But what I want to do is get it down to one shortcut and ideally switch focus back to the text editor so I can carry on writing my tests. Well, a quick macro bound to the shortcut Ctrl+T and I am partway there. The macro I have runs both previous commands for me but it doesn’t yet put the focus back to the text editor. I will hopefully crack this soon but I just wanted to post all this first.

Here’s the macro. Remember to bind it to your shortcut of choice.

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module ChainedCommands

    Public Sub RunSelectedUnitTestSession()
        Dim selection As TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
        Dim textPoint As TextPoint = CType(selection.ActivePoint, TextPoint)
        Dim line As Integer = textPoint.Line
        Dim offset As Integer = textPoint.LineCharOffset
        Dim index As Integer

        DTE.ExecuteCommand("ReSharper.ReSharper_ShowUnitTestSessions")
        DTE.ExecuteCommand("ReSharper_UnitTestSession_RunAll")

        selection.MoveToLineAndOffset(line, offset)
    End Sub

End Module

I’ve been using a BDD macro based on the one JP Boodhoo published for getting more descriptive test names along with a R# template so that I can type “test” + tab, type the test name (with spaces) and then hit Alt+- and voila – BDD style test names.

This worked well for a while until some point where R# started to do autocompletion on the test name as I typed (for instance, typing ‘Check that blah is not null’ often ended up as ‘Check that blah is NotImplementedException null’). That was OK though after a quick rework of the R# template and macro so R# wraps the test name in quotes which the macro then removes.

But R# doesn’t format the end result as well (the method braces don’t indent correctly) and this bugged me for a while.

So, a quick change to the macro and the R# template and now it’s much more smooth. Typing ‘tests’ + tab and R# outputs public class “FIXTURENAME” (with fixturename highlighted and ready to type over). Type out the name of the fixture, Alt+- and the macro replaces spaces, puts in the [TestFixture] attribute, drops in the opening and closed braces and puts the caret right where I want it. Sweet.

Do the same with ‘test’ + tab, type test name, Alt+- and you get the same for a test. Extra sweet.

This is the BDD macro:

   1: Imports System
   2: Imports System.Windows.Forms
   3: Imports EnvDTE
   4: Imports EnvDTE80
   5: Imports System.Diagnostics
   6:  
   7: Public Module CodeEditor
   8:     Private Const INDENT_SIZE As Integer = 4
   9:  
  10:     Public Sub ReplaceSpacesInTestNameWithUnderscores()
  11:         If DTE.ActiveDocument Is Nothing Then Return
  12:         Dim wrCS As Boolean = DTE.Properties("TextEditor", "CSharp").Item("WordWrap").Value
  13:  
  14:         Try
  15:             DTE.Properties("TextEditor", "CSharp").Item("WordWrap").Value = False
  16:             Dim selection As TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
  17:             Dim textPoint As TextPoint = CType(selection.ActivePoint, TextPoint)
  18:             Dim line As Integer = textPoint.Line
  19:             Dim offset As Integer = textPoint.LineCharOffset
  20:             Dim index As Integer
  21:  
  22:             selection.SelectLine()
  23:             If selection.Text = "" Then Return
  24:  
  25:             Dim methodIndex As Integer = selection.Text.IndexOf("public void ")
  26:             Dim classIndex As Integer = selection.Text.IndexOf("public class ")
  27:  
  28:             If (methodIndex < 0 AndAlso classIndex < 0) Then
  29:                 selection.MoveToLineAndOffset(line, offset)
  30:                 Return
  31:             End If
  32:  
  33:             index = CType(IIf(methodIndex >= 0, methodIndex, classIndex), Integer)
  34:  
  35:             If methodIndex >= 0 Then
  36:                 HandleTestMethod(selection, index)
  37:             Else
  38:                 HandleTestClass(selection, index)
  39:             End If
  40:         Catch ex As Exception
  41:             MsgBox(ex.Message)
  42:         Finally
  43:             DTE.Properties("TextEditor", "CSharp").Item("WordWrap").Value = wrCS
  44:         End Try
  45:     End Sub
  46:  
  47:     Private Sub HandleTestClass(ByVal selection As TextSelection, ByVal index As Integer)
  48:         Dim whiteSpace As String = GetWhiteSpace(selection, index)
  49:         HandleTestNameFormatting(selection, "public class ", index)
  50:         AddAttribute(selection, index, "[TestFixture]", whiteSpace)
  51:         AddBraces(selection, index, whiteSpace)
  52:     End Sub
  53:  
  54:     Private Sub HandleTestMethod(ByVal selection As TextSelection, ByVal index As Integer)
  55:         Dim whiteSpace As String = GetWhiteSpace(selection, index)
  56:         HandleTestNameFormatting(selection, "public void ", index)
  57:         AddAttribute(selection, index, "[Test]", whiteSpace)
  58:         AddBraces(selection, index, whiteSpace)
  59:     End Sub
  60:  
  61:     Private Sub AddAttribute(ByVal selection As TextSelection, ByVal index As Integer, ByVal attribute As String, ByVal whiteSpace As String)
  62:         selection.LineUp()
  63:         selection.SelectLine()
  64:         If selection.Text.Trim <> attribute Then
  65:             selection.Insert(selection.Text & whiteSpace & attribute & vbCrLf)
  66:         End If
  67:         selection.LineDown()
  68:     End Sub
  69:  
  70:     Private Function AddIndent(ByVal spacer As Char) As String
  71:         Return String.Empty.PadRight(INDENT_SIZE, spacer)
  72:     End Function
  73:  
  74:     Private Sub AddBraces(ByVal selection As TextSelection, ByVal index As Integer, ByVal whiteSpace As String)
  75:         selection.SelectLine()
  76:         If selection.Text.Trim <> "{" Then
  77:             selection.Insert(String.Format("{0}{4}{1}{0}{2}{1}{0}{5}{1}{3}", whiteSpace, vbCrLf, AddIndent(whiteSpace(0)), selection.Text, "{", "}")) ' & whiteSpace & AddIndent(whiteSpace(0)) & vbCrLf & "}" & vbCrLf)
  78:             selection.LineUp()
  79:             selection.LineUp()
  80:             selection.LineUp()
  81:             selection.EndOfLine()
  82:         Else
  83:             selection.LineUp()
  84:             selection.EndOfLine()
  85:         End If
  86:     End Sub
  87:  
  88:     Private Function GetWhiteSpace(ByVal selection As TextSelection, ByVal index As Integer) As String
  89:         Return selection.Text.Substring(0, index)
  90:     End Function
  91:  
  92:     Private Sub HandleTestNameFormatting(ByVal selection As TextSelection, ByVal prefix As String, ByVal index As Integer)
  93:         Dim whiteSpace As String = GetWhiteSpace(selection, index)
  94:         prefix = whiteSpace + prefix
  95:         Dim description As String = selection.Text.Replace(prefix, String.Empty).Trim
  96:         If description(0) = """" Then
  97:             Dim lastQuote As Integer = description.LastIndexOf("""")
  98:             If lastQuote = 0 Then
  99:                 description = description.Substring(1)
 100:             Else
 101:                 Dim endOfDescription As String = description.Substring(lastQuote + 1)
 102:                 description = description.Substring(1, lastQuote - 1) + endOfDescription
 103:             End If
 104:         End If
 105:         Dim text As String = prefix + description.Replace(" ", "_").Replace("'", "_") + vbCrLf
 106:         selection.Delete()
 107:         selection.Insert(text)
 108:         selection.LineUp()
 109:     End Sub
 110: End Module

For the ReSharper templates, open up the live templates and add a template called ‘tests’ with the body of template as below:

public class "$FIXTURENAME$"

And then another one called ‘test’ with the body as

public void "$TESTNAME$"()

Mark both of these as available for C# only (or if for VB.Net, adjust the template body for the VB equivalent), and for the ‘test’ one, mark this as available only where a method declaration is allowed.

That’s it. Now you can get into the flow of typing ‘test’ TAB ‘name of test’ Alt+- and then typing in the test itself.

I have a confession to make. I’m a Resharper junkie. I’m addicted to it and just can’t work with a naked Visual Studio any more. I’ve tried hiding this since the early 1.something days (1.65? it’s a bit of a blur) but I can’t any more.

OK – anyone that knows me will know that I haven’t hidden this fact very well and that in fact I try to spread my addiction to others. Well now I have good news. Jetbrains have a partner program and if you drop me your details then I can arrange for a 60 day trial of Jetbrains products and if you do purchase then you will get between 5%-10% off the purchase price.

Obviously I will benefit in some way beyond the simple fact that I have helped spread the joy to others but let’s face it – that is reward in itself 😉

OK – it has been a long long LONG time coming but I have finally bitten the bullet and got a blog. The thing that finally motivated me enough is that I’m doing a talk at the Cambridge SPA group on June 11th about Dependency Injection (and will hopefully get the chance to give the same talk at Skills Matter).

So, that is the motivating reason for the blog. I now plan to follow up this starting post with many others.