Hello again and welcome to the latest edition of Developing PixelBugs. This time around we’re not adding any new features, but instead we’ll be adding a service layer and some refactoring. During this process I found a reason to upgrade to the Castle trunk from RC3, but more on that later.
Adding a service layer
So far we haven’t anywhere for our business logic to sit. It shouldn’t sit in the controllers and it shouldn’t sit in the repositories. So we need the service layer. To cover the functionality so far we need to add two services, one for security and one for managing issues.
I first created a new interface called ISecurityService which has two methods. One for authenticating a user from their username and password and returns a security token. The second method validates a security token and returns the authenticated user:
Next I added some unit tests for this service and refactored the existing security controller tests so that the controller now only takes an ISecurityService as a constructor argument. I modified the tests as required to work with this new interface (going through the normal process) and registered the service with Windsor (via a new services.config file) to allow the acceptance tests to pass. I also refactored the authentication filter tests to use ISecurityService and the authentication filter implementation.
All the tests are now passing. I really see the value in tests now and have full confidence that it’s all working after the significant change I’ve just made.
Next I followed the same process to add another service called IIssueService for use by the issue controller:
After completing the process, all tests are passing
Refactoring
Once the service layer was in I decided to carry out some refactoring. Here’s what I did:
I want to stop using the session to store stuff, so I now store the security token in a cookie rather than the session. This avoids the timeout problem and keeps the user signed in until they sign out. This was great except that one of my tests (Authenticate_Success) failed with a NotSupportedException. This was due to Castle RC3 test support not implementing CreateCookie. So I now have the perfect reason to upgrade to the trunk. This is something I always planned to do, but now I have a reason to do it now (see details below).
Here are some other refactorings:
- Refactored views to use url helper rather than hard-coded ($Form.FormTag and $Url.Link)
- Moved base test classes to PixelDragons.Commons.TestSupport
- Removed duplication where possible
Upgrading to Castle trunk
Here are the tasks I performed to upgrade from Castle RC3 to the trunk. I found some of the information I needed here:
- Using TortoiseSVN, connect to the Castle SubVersion server and get the latest committed code (details here)
- Run the build without tests using NAnt (see “How to build.txt”)
- Replace the Castle assemblies in our lib folder with the newly built ones
- Tried to build the solution which resulted in LOTS of errors
- Updated the filter Perform method from
public bool Perform(ExecuteEnum exec, IRailsEngineContext context, Controller controller)to
public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller, IControllerContext controllerContext) - Replaced all
using NHibernate.Expressionwithusing NHibernate.Criterion - In UserRepository changed
new EqExpressiontoExpression.Eq - In facilities.config I removed the “hibernate.” prefix from the arfacility config settings
- In facilities.config I removed the startable facility
- In facilities.config I replaced
Castle.MonoRail.WindsorExtension.RailsFacilitywithCastle.MonoRail.WindsorExtension.MonoRailFacility - Removed the HttpModule
Castle.MonoRail.Framework.EngineContextModulefrom the web.config
Test Coverage
Once all of this was done and the tests were all passing again. I thought I better check my test coverage, so I downloaded the last free version of NCover and NCoverExplorer and gave it a run. I found a few areas that weren’t covered by my tests, so I added more tests. We now have 40 passing tests:
and pretty good coverage (apart from PixelDragons.Commons):
So that’s it for this time. Not much of a post I know but hey. As usual the code is committed to Google Code, so feel free to take a look.
Url: http://code.google.com/p/pixelbugs/
Svn Revision: r10
Filed under: Architecture, Refactoring