.net and other musings

Ben Lovell, an agile developer living in the UK.

Category: Windsor

Incremental development with Monorail: Part Seven

Since our last installment I slipped in a ninja-edit to one of the configuration files. This was to ensure that our sole service was marked as transient rather than the default Windsor lifestyle of singleton. This was pointed out to me by an eagle-eyed commenter and was an oversight on my part. So we’re now at rev10 and ready to roll once again!

In our last post we tidied up a few bits and improved our code-base rather than actually adding features as such. This time we’re going to move down into the persistence and start to drive out this notional layer.

We’re going to handle data access using the repository pattern. The repositories will work on our ActiveRecord entities ensuring they’re persisted to our database. We will introduce a new interaction between our service BlogPostService and the newly introduced repository interface IBlogPostRepository. Let’s get on and write a test:

71

The test above is fairly self-explanatory. We’ve introduced the IBlogPostRepository and we’re passing it into our BlogPostService which should then call the Save method passing our mapped post. We need to get rid of the red code and get the test passing, so first we must create our new interface, and then modify the service constructor:

72

73

We need to modify our other tests that construct the BlogPostService as they’re still assuming only a single argument constructor exists. As we have some duplication going on we’ll push this construction up into our setup code:

74

We should be able to run our tests in this fixture now:

75

As expected, since our BlogPostService doesn’t actually do much with our repository yet, we need to do some pretty minor tweaking to pass this test:

76

Let’s try again now:

77  Cool, let us try and run the whole suite including our integration type tests:

78

The integration tests are failing as we’ve yet to map the new dependency in our Windsor configuration. We can specify this now:

79

We still have failing integration tests though, so we need to add the BlogPostRepository specified in our configuration:

80

As you can see it doesn’t do much, but we just want our tests passing at this stage. Let’s run the whole suite of tests now:

81

Great, we have a working product once more. I’m going to finish here, as ever, the latest changes have been committed:

http://code.google.com/p/mr-blogengine/

Next time we’ll make our new repository more useful and finally hit the database!

Advertisements

Incremental development with Monorail: Part Six

We finished up in part five with a full suite of passing tests and our BlogPostService is slowly taking shape now. The next few posts will introduce persistence and validation but before we get started on these features, we have a little housekeeping to perform on our existing code.

First step is to build the Castle trunk and update our references to the latest versions. Secondly, we’ll incorporate a few changes suggested by Hammett.

After building and replacing our references with the latest Castle build I’ll run the tests as a sanity check before we proceed:

62

With that out of the way our first code change will ensure we play nicely with HTTP. It is considered good practice to ensure requests which update or create resources is carried out via POST – so we can modify our only PostController.Save action to ensure this is so but before we do this we’ll write a test:

60

Running our test produces the following:

61

We’ll modify our Save action now to ensure we only accept the POST verb:

63

We have added the AccessibleThrough attribute and explicitly specified that our action must only allow the POST verb. We’ll run our test again and make sure everything is working as expected:

64

The next step is to modify our add.vm view to use the helper methods to generate our form tags. We’ve done that and once again we’ll run our tests:

65

I’m noticing a little duplication creeping in to our integration tests that should be removed. Also, until now we’ve had to assume that a web server is running on a specific port on our development machine in order to run the integration tests. Through a little tweaking we can spin-up a temporary server in our test fixture setup code and host our test code there instead.

First we add the WebDev.WebHost.dll to our lib project directory and ensure we’re referencing this from the testing project. The next step is to create an app.config file in the testing project so we can configure where and from which port our testing server should be hosting from:

66  Now we add some setup code for the fixture:

67

We’ll also make sure we bring the server down when we’re finished:

68

Now ensure the VS web server is not running on the same port, then we can run our tests and make sure our latest changes work out:

69

Now, since we specify the web root and port through configuration, we should also use these configurable values to determine the URLs in our tests:

70

You can see our tests now call BuildTestUrl to determine the full URL where we’re hosting the development server. Neat. I’m sure when we add further integration fixtures we’ll extract class this, but for now we have a nice working set of tests and should remember the principle of YAGNI!

I’m going to cut this installment short here. In the next post we’ll get back into the swing of it and continue implementing features.

As ever, the latest code has been checked in and is available here:

http://code.google.com/p/mr-blogengine/

Incremental development with Monorail: Part Five

Welcome back. In this post I’ll be getting our tests passing again and cleaning things up a little. We left off with a failing integration test:

42

I suspect this is due to the IBlogPostMapper dependency we introduced to our BlogPostService not being handled by the container. If we run in the browser we can confirm this is in fact true:

As we’ve yet to implement our IBlogPostMapper we must go ahead and do this before we can add the container configuration to pass our integration test. Lets bust out a test and get things rolling:

43

We have a few blanks to fill in in order to get this to compile and run:

  1. Make the DTO’s properties virtual so we can mock them. This is in preference to extracting an interface.
  2. Implement IBlogPostMapper.
  3. Add the necessary properties to the IBlogPost interface.

Lets go ahead and do this now:

44

IBlogPostMapper minimal implementation:

45 

The necessary modifications to IBlogPost:

46

Now we can compile and run our test:

47

Our BlogPostMapper implementation is throwing an exception so lets go back and take another step to try and pass our test:

48

BlogPost:

49

I’m pretty certain we’ve done enough to pass our test now. Lets have a go:

50

OK now lets focus on the full suite:

51

Our integration test is still bombing but as we’ve got a mapper now, we can go ahead and wire up our Windsor configuration and get things moving again:

52

We’ve added another configuration file: mapper.config and referenced this from the web.config. We shouldn’t need to do any more than this so lets run our full test suite:

53

Our full suite is passing now. Not bad for 5 minutes work! As usual the latest changes are checked in to the Google code project hosted here.

Now we have a full passing suite, in our next edition I’ll be moving down into the persistence and also incorporating a few modifications from Hammett. Stay tuned!

Dependency injection with Monorail and Windsor

Dependency Injection (or IoC) is a practice I apply when designing software. It enables enforcement of the Single Responsibility Principle and also has the added side effect of producing more testable code.

Scott Bellware has posted an excellent write-up on dependency patterns and it got me thinking about my favoured approach with dependency injection and how the Castle Windsor container provides that for us. I favour constructor based DI as it enforces the fact that your class must be wired up during initialisation. It makes your dependencies highly visible and as Scott mentions – goes some way to producing a self-documenting API.

Some of the common alternatives, or perhaps complimentary approaches include resolving dependencies from the container or service locator hidden in the constructor (dirty), or the provision of property setters for your dependent interfaces. Of course providing getters (or at least public getters) is a no-no as you would be exposing your dependencies to consumers thus violating encapsulation. But I guess this goes without saying?

Thankfully, Monorail controllers and their dependencies can be wired up using constructor based DI via RailsFacility and Windsor integration. Take the following example:

dependencies

ContactController in the diagram above is a simple Monorail controller that depends on the IContactService to carry out most of its work. Stemming from there the IContactService implementation has dependencies on IContactRepository and an external library (from NSpectre) interface IValidatorFactory which is created using the Windsor factory facility and some custom factory code, but more on that later… As you can see from the model, the dependencies are injected via constructor arguments.

Using the RailsFacility is fairly simple, rather than me explaining it I’ll point you to the docs here. Once you’ve got the facility and container set up, you simple declare your controllers and their dependent components via configuration:

<component id="contact.controller" type="Campaigns.Controllers.ContactController, Campaigns.Controllers">
      <parameters>
        <mailTo>benjamin.lovell@gmail.com</mailTo>
        <subject>Contact message from Website</subject>
      </parameters>
    </component>

I’ve explicitly declared some of the required values for the ContactController constructor above. Just as reminder the signature for ContactController  constructor:

public ContactController(IContactService contactService, string mailTo, string subject)

When the ContactController is wired up by windsor the IContactService contactService argument is resolved to the following service configured in my components.config file:

<component id="contact-service"
               service="Campaigns.Core.IContactService, Campaigns.Core"
               type="Campaigns.Services.ContactService, Campaigns.Services">
    </component>

Of course, ContactService also joins in the fun and has its dependencies injected via the same means:

<component id="contact-repository"
               service="Campaigns.Core.IContactRepository, Campaigns.Core"
               type="Campaigns.Repository.ContactRepository, Campaigns.Repository" />

Windsor detects that the ContactService constructor takes a IContactRepository argument and resolves this automatically.

Now for the keen-eyed among you, and going back to my point earlier regarding the IValidatorFactory dependency… This is resolved using the natty Windsor factory facility, the best explanation of which is here. In my configuration I state that IValidatorFactory dependencies should be resolved via my custom factory code:

using NSpectre.Core;
using NSpectre.Core.Configuration;
using NSpectre.Core.Implementation;

namespace Campaigns.Core
{
    /// <summary>
    /// Factory for NSpectre validators
    /// </summary>
    public class NSpectreFactory : INSpectreFactory
    {
        #region Fields

        private readonly string xmlEmbeddedResourcePath;
        private readonly bool saveGeneratedCode = false;
        private readonly string path;

        #endregion

        #region Constructors

        /// <summary>
        /// Initialises the factory with the embedded resource path.
        /// </summary>
        /// <param name="xmlEmbeddedResourcePath">The path to the embedded resource.</param>
        /// <param name="saveGeneratedCode">Save the generated code</param>
        /// <param name="path">The path to save the code to</param>
        public NSpectreFactory(string xmlEmbeddedResourcePath, bool saveGeneratedCode, string path) : this(xmlEmbeddedResourcePath)
        {
            this.saveGeneratedCode = saveGeneratedCode;
            this.path = path;
        }

        /// <summary>
        /// Initialises the factory with the path to the NSpectre configuration embedded resource.
        /// </summary>
        /// <param name="xmlEmbeddedResourcePath"></param>
        public NSpectreFactory(string xmlEmbeddedResourcePath)
        {
            this.xmlEmbeddedResourcePath = xmlEmbeddedResourcePath;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the path to the configuration embedded resource.
        /// </summary>
        public string XmlEmbeddedResourcePath
        {
            get { return xmlEmbeddedResourcePath; }
        }

        /// <summary>
        /// Gets a flag indicating whether NSpectre should save the generated code.
        /// </summary>
        public bool SaveGeneratedCode
        {
            get { return saveGeneratedCode; }
        }

        /// <summary>
        /// Gets the path to save the generated code to.
        /// </summary>
        public string Path
        {
            get { return path; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Creates the validator factory
        /// </summary>
        /// <returns>The validator factory, initialised</returns>
        public IValidatorFactory CreateFactory()
        {
            IConfigurationReader reader = new EmbbeddedXmlResourceConfigurationReader(xmlEmbeddedResourcePath, new NullLogger());
            Initialiser initialiser = new Initialiser();

            if (SaveGeneratedCode)
                return initialiser.CreateValidatorFactory(reader, saveGeneratedCode, path);
            else
                return initialiser.CreateValidatorFactory(reader);
        }

        #endregion
    }
}

The custom factory is hooked up using the following configuration:

<component id="nspectre.factory" 
               service="Campaigns.Core.INSpectreFactory, Campaigns.Core" 
               type="Campaigns.Core.NSpectreFactory, Campaigns.Core">
      <parameters>
        <xmlEmbeddedResourcePath>Campaigns.Core.Model.NSpectreValidations.xml, Campaigns.Core</xmlEmbeddedResourcePath>
      </parameters>
    </component>

    <component id="nspectre.default" 
               type="NSpectre.Core.IValidatorFactory, NSpectre.Core"
               factoryId="nspectre.factory"
               factoryCreate="CreateFactory" />

You really notice the effectiveness of this approach when adding new controllers to your project. You simply add the controller code, define its dependencies in the constructor and add the configuration for the controller to your controllers.config file and everything is resolved and injected for you at runtime. Very nice indeed, I’m sure you will agree!

Testing is made easy by providing dynamic mocks. To make this an even nicer experience take a look at the AutoMockingContainer from the nice folks at Eleutian!

To wrap up I have to say: Castle really does kick the llama’s ass.