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.

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.

For this post we are going to enable auto registration in the container and see what benefits it can bring us.

What is auto registration?

What we mean by this is that we would like all our controllers and all the services those controllers depend on (and any dependencies they may have) to be automatically registered into the container for us. This saves us the extra step of manually registering them in the xml configuration.

The ability to auto register components into the container should be available in the last castle release (I haven’t checked to be honest) but what I want to show is the reduced friction way of enabling this. To do this we need to grab one of the later builds of castle.

Getting the latest castle builds

The castle project publishes all builds to http://builds.castleproject.org (which at the time of writing this just happens to be down at the moment which is the first time I’ve ever seen it down). On here you will see all successful and failed builds. If you explore the details of any of these builds you’ll also see a whole load of unit tests that are run as part of the build. This is a practice that I highly recommend following.

For this example I’ve grabbed build 967. Unzip the contents of the build and copy the bin folder contents into your tools/castle directory.

Before running the application there are two slight changes that need to be made. The first one is that when using later builds you will get an error when you navigate to your site with “Could not load type ‘Castle.MonoRail.Framework.EngineContextModule’ from assembly ‘Castle.MonoRail.Framework’“. To fix this, edit the web.config and remove the ‘monorail’ Http Module from the system.web/httpModules section.

The other change is with the windsor integration. A change was made to the windsor extension called RailsFacility which is now called MonoRailFacility instead. Make this change within the facilities.config file.

With these slight changes in place we should be able to now build and run our application.

So now onto the real guts of this post.

What we want to first do is auto register all our controllers. Each of our controllers is ultimately an IController so what we really want to do is auto register all IController classes into the container.

We do this within GlobalApplication.cs (the codebehind for global.asax) within the Application_OnStart method. You’ll already see that this is where the container get’s initialised for the whole application, passing in a new instance of XmlInterpreter with no parameters which tells windsor to look in web.config for the configuration.

public void Application_OnStart()
{
    container = new WindsorContainer(new XmlInterpreter());
}

We then add the following line beneath this to get windsor to automatically register all controllers:

container.Register(
    AllTypes.Of<IController>()
    .FromAssembly(Assembly.GetExecutingAssembly()));

Hmm – a nice bit of fluent interface goodness there. So here we are looking for all types of IController from the executing assembly and registering them into the container.

If we build and run our application everything works as it should but there’s a little gotcha (it’s actually a good gotcha) in that this new line of code won’t do much for us right now as we are still explicitly registering our controllers in the controllers.config file. The container still loads and resolves item in the config files first. When the auto registration code is invoked it will skip over any controllers that have already been explicitly registered manually. This enables us to override the auto registration so we still have flexibility when we need it.

So if we now go into our controllers.config and remove all the existing controller registrations and rerun the application there should be no change and now all our controllers are being auto registered.

If we now run our application then our BookController is still retrieved from the container (as it was auto registered) and the container is still satisfying it’s dependency on the BookRepository (as it is still manually registered).

To get our services (and other components) auto registered we make a further change to GlobalApplication.cs and add the following:

public void Application_OnStart()
{
    container = new WindsorContainer(new XmlInterpreter());
    container.Register(
        AllTypes.Of<IController>()
        .FromAssembly(Assembly.GetExecutingAssembly()));
    container.Register(
        AllTypes.Pick()
        .FromAssembly(Assembly.GetExecutingAssembly())
        .WithService.FirstInterface());
}

Here we’re now selecting all types from the executing assembly (our web app) and registering them into the container. We are also specifying WithService.FirstInterface. What this enables is that for any types that implement an interface, use the first interface as the ‘service’ to register the type against.

If we introduce an IBookRepository interface (something we will do at some point btw) and changed BookRepository to implement this interface then as long as IBookRepository was the first interface BookRepository implemented then it would be registered into the container against that interface.

So if we changed our BookController to depend on IBookRepository then it would all still be auto registered and wired up correctly as we expect.

This is actually one of the great things with using auto registration in that we can make this changes without having to manually change the configuration. It also allows us to add new controllers, again without having to worry about the manual configuration changes. This allows us to focus on coding and providing a solution in a more friction free manner.

Now to test our application. First off, change components.config to remove our manual BookRepository configuration.

As you should see, our application loads and runs as it did before but now with our controllers, services and supporting components all auto registered for us.

Next steps

So far we haven’t explored the benefits of Monorail in regards to unit testing, and we’ve mentioned about introducing IBookRepository which will give us some flexibility to our implementations. I’m intending that one of those implementations will be using NHibernate and we’ll be using Fluent NHibernate to handle our mapping for us. Let’s see if I can pull those out of the bag quicker than I’ve pulled this one out:)

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.

We’ve downloaded and installed Monorail and had a look at the solution that the wizard generated for us. Now we are going to add a new controller.

In this series of posts we will start to build an application but for now I just want to see what is involved with adding a new controller and associated views and maybe lean on the Windsor integration a bit. As we move towards building our application we will move over to a test first driven approach and explore how testable Monorail is.

So for now, without further ado, let’s add a new controller.

The application I want to build through this series is going to be a book lending service. I have a load of development focused books that I recommend and lend to colleagues at the contracts I work at but I occasionally forget who I’ve lent books too so this application will help relieve this burden (and we’ll see if we can add some real value to the app as we progress).

So for now I would like a way of just taking in a list of Books (our model) and show them in the view, all the while coordinating this activity through the controller.

So first up, we’ll create a BookController and we’ll inherit from BaseController for now. We’ll then add an Index method. You should now have this very empty controller:

   1: namespace BookLendingService.Controllers
   2: {
   3:     public class BookController : BaseController
   4:     {
   5:         public void Index()
   6:         {
   7:  
   8:         }
   9:     }
  10: }

We now need to add the associated view by adding a new folder under Views called Book and then we need to add an Index.vm file. Add it as a text file so it is empty.

Now we’ll build it and view the site by navigating to /book/index.castle. We should expect to see a page with just the existing layout applied to it as we are inheriting from BaseController. Instead, we get an error page.

Controller not found. Area  Controller Name book - Windows Internet Explorer

The reason for this is that because we enabled the Windsor integration we now need to register our controllers into the container. Castle Windsor is an Inversion of Control container for enabling us to use Dependency Injection. This will help resolve our dependencies but for now we have introduced a slight bit of pain (for long term gain) by adding an extra step to the process.

The Windsor configuration is held under the config folder. The one we need to add to is the controllers.config file. Open it up and add the following line:

<component id="book.controller" type="BookLendingService.Controllers.BookController, BookLendingService" />

You’ll need to change BookLendingService to whatever you’ve called your application but apart from that you should now be able to build the app again and view the page.

OurFirstEmptyController

Now we’ll extend this to get a list of books, so we need to introduce our Book model. For now our book will have a title and description. This new Book class will be added to the Models folder:

   1: namespace BookLendingService.Models
   2: {
   3:     public class Book
   4:     {
   5:         private string title;
   6:         private string description;
   7:  
   8:         public Book()
   9:         {
  10:         }
  11:  
  12:         public Book(string title, string description)
  13:         {
  14:             this.title = title;
  15:             this.description = description;
  16:         }
  17:  
  18:         public string Title
  19:         {
  20:             get { return title; }
  21:             set { title = value; }
  22:         }
  23:  
  24:         public string Description
  25:         {
  26:             get { return description; }
  27:             set { description = value; }
  28:         }
  29:     }
  30: }

In our controller we’ll just create a dummy list of books within the index method and assign it to a books property bag item.

   1: using System.Collections.Generic;
   2: using BookLendingService.Models;
   3:  
   4: namespace BookLendingService.Controllers
   5: {
   6:     public class BookController : BaseController
   7:     {
   8:         public void Index()
   9:         {
  10:             List<Book> books = new List<Book>();
  11:             books.Add(new Book("Our First Development Book", "This is our first development book to go into our list of books"));
  12:             books.Add(new Book("The Pragmatic Programmer", "A fantastic book that is as relevant today as it was yesterday. Highly recommended."));
  13:             books.Add(new Book("Working Effectively with Legacy Code", "Another fantastic book which now applies to this application as we aren't writing tests."));
  14:             PropertyBag["books"] = books;
  15:         }
  16:     }
  17: }

And in our view (book/index.vm) we can now iterate over our collection of books and display them in the view.

   1: <h1>Our Book Listing</h1>
   2:  
   3: <ul>
   4: #foreach ($book in $books)
   5:     <li>$book.Title</li>
   6: #end
   7: </ul>

And a quick build and refresh of our page gives us our listing of books by title.

OurBookListing

And that’s it. We’ve now added our first controller, an initial view for listing out our books, and a starting book model. At the moment it is very raw but we have something we can expand upon.

I think the next post (it’s running late and I’m not working to a set plan here – so is likely to change) will be looking at moving out how we get our list of books in the controller into a BookRepository, wiring that up via Windsor, and maybe seeing if we can get rid of some of the configuration pain by using auto registration of our controllers.

We’ve now run through the initial wizard to get our starting Monorail application up and running. We’re now going to explore what the wizard has generated for us.

Solution StructureSolutionExplorer

Here’s our generated solution with our web project and our test project. Monorail is an MVC web framework and the wizard has generated a project structure for us for containing our Models, Views and Controllers. We also have a folder for static content and the Windsor integration has given us a config folder.

Our Models folder contains our starting business objects/entities. As our application grows, these might get pushed out into their own project to form a domain model or they may stay as a presentation model. For now we’ll gloss over them a little at least until we explore Castle Active Record.

The views and controllers have a linked structure as each controller has a corresponding folder under the views folder. These individual view folders then contain a .vm file for each action that can be performed on the controller. These .vm files are the NVelocity templates and contain our presentation only, including some lightweight presentation logic to loop over collections or other presentation specific operations.

Now, looking at the controllers folder we have 3 controllers listed (Contact, Home and Login) along with BaseController. If we look further we can see that each of the 3 controllers inherits from BaseController, which in turn inherits from SmartDispatcherController. In Monorail, a controller is a class that inherits from Controller but usually you will use the SmartDispatcherController as this provides us with some very powerful data binding capabilities.

A closer look at a controller

OK, so let’s crack open one of our starting controllers and see what we can find. Since we are on the home/index.castle page then let’s pick on the HomeController as this is the one that maps to our current page.

Looking inside HomeController we have 2 public methods called Index and BlowItAway. Both are actions on the controller and our current page of home/index.castle maps to the Index method.

Within the Index method we see an assignment to PropertyBag. The PropertyBag is one of a couple of ways of passing information over to a view from the controller. By assigning DateTime.Now to PropertyBag[“AccessDate”] we are giving the view the current time via a view variable of “AccessDate”. If we open up the Views/Home/Index.vm file we can use this variable. Find the <div id=”greeting”> line and add the following new div below it:

<div>The time is $AccessDate</div>

Save the Index.vm file and refresh your browser. You should now see the date and time output. At the moment it doesn’t look very pretty but notice how we’ve output a dynamic variable without jumping through the usual ASP.NET escaping into server code in the page. Our usual way of doing this would be something like <div>The time is <%= DateTime.Now %></div>.

Not only that, but we haven’t embedded the logic of using DateTime.Now within the page itself. The controller is where we decide this type of logic and the view itself remains very light. In my mind this is one of the big benefits of using Monorail, it is naturally guiding us to separate our logic from our views. This is possible with web forms but it’s something we have to enforce ourselves and it is very easy to slip back into bad habits (well, it is for me anyway).

But now lets fix the ugly nature of our date time format. Change the view code to <div>The time is $AccessDate.ToString(‘HH:mm’)</div>. Now we get just the time output. NVelocity is dynamically calling the ToString for us.

But have we just mixed logic that the controller should be handling for us? That depends. If it’s something that needs to be enforced and testable then keep the view light and just output $AccessDate and change the controller to push the correctly formatted time into the property bag.

OK – this wraps it up for our explore of the starting application for now. For our next post we’ll add a new controller and wire it up with Windsor.

I’m planning on this being a start of a series of posts on Monorail, the MVC web framework from the Castle Project (www.castleproject.org). So, how to get started with Castle Monorail.

The first starting point is to download the last full release which is 1.0 Release Candidate 3. This is the first potential stumbling block for many in that it is a release candidate rather than a full release and has remained in this state since September 2007. However, the whole castle stack is, from my experience, very stable with a whole array of tests and is actively being developed.

Once downloaded, install and you should now have all the binaries etc located under C:\Program Files\CastleProject. This includes the Visual Studio integration to provide a Monorail and Active Record project types to get you started (although only available for VS2005 at this point in time).

Now, fire up VS2005 and create a new project. Select Visual C#->Castle Monorail Project. This will start up the Monorail project wizard.

Castle VS Wizard 1st Screen

For an initial getting started we’ll stick with the NVelocity view engine but we’ll enable Windsor integration as we’ll lean on this in a following post. We’ll also ignore the routing engine for two reasons. For one, we don’t really need it right now, and the other more important reason is that it causes an error with the end project. OK, next screen.

Castle VS Wizard 2nd Screen

For now, we’ll ignore these options but we’ll come back to the Active Record Integration in a later post.

Castle VS Wizard Last Screen

The last wizard screen asks us if we are a TDD enthusiast and if selected gives us a separate test project using NUnit as the test framework. Keep this option selected and hit Finish.

We now have our starting Monorail project. To see it in action select the properties of the project and set the web properties to use either IIS or the VS Development Server and hit F5.

Monorail Starting Application 

You should get the homepage as above. This is the starting Monorail application generated by the wizard and gives us everything we need for starting out with Monorail and the ending point for this blog post. Further posts will explore the different elements of Monorail, its testability and the Windsor integration.

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
Follow

Get every new post delivered to your Inbox.